Adding a Drop Shadow to Panel

Jo SRM 116 Reputation points
2021-01-12T20:37:18.217+00:00

WINFORMS C#
Visual Studio 2017

I have a movable panel that will contain other controls. I wanted to add a DropShadow effect to the panel to make it look good, so I used the following code:

private DevExpress.Utils.FormShadow.PopupFormShadow ShadowNew = new DevExpress.Utils.FormShadow.PopupFormShadow();  
//Assigned the panel  
ShadowNew.Form = panelControl1;  

The code to hide the shadow is:

ShadowNew.Form = null;  

This works beautifully, that is until I scroll. Parts of the Panel is not viewable which is normal, but the shadow for that part is still viewable. What I am trying to do now is look for a way to detect when the panel or part of the panel is not viewable when using the scrolling so that I can then hide the shadow, and when the panel is completely viewable show the shadow.

55776-shadow-showing.gif

Any suggestion

I am looking for an alternative drop shadow but nothing really looks as good as this.

Sincerely and regards,

Windows Forms
Windows Forms
A set of .NET Framework managed libraries for developing graphical user interfaces.
1,894 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,962 questions
0 comments No comments
{count} votes

Accepted answer
  1. Jo SRM 116 Reputation points
    2021-01-13T16:37:25.463+00:00

    I was able to find a solution in VB code here: showthread.php

    Partial C# code is:

    // This will verify if the right side of the panel is not in the forms viewable area and will hide the shadow, else it will show it.
    Rectangle myBounds = this.ClientRectangle;
        if (myBounds.Right < panelControl1.Right)
         {
            ShadowNew.Form = null;
         }
                else
         {
          ShadowNew.Form = panelControl1; 
         }
    

    56247-shadow-not-shown.gif

    Thank you for the support.

    0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Daniel Zhang-MSFT 9,626 Reputation points
    2021-01-13T07:49:20.637+00:00

    Hi JoSRM-1861,
    You can try to use GraphicsPath to draw a smooth shadow.
    Here is a test coed example you can refer to.

    public Form1()  
    {  
        InitializeComponent();  
        shadowControls.Add(panel1);  
        this.Refresh();  
    }  
    List<Control> shadowControls = new List<Control>();  
    Bitmap shadowBmp = null;  
    Point PanelMouseDownLocation;  
    private void panel1_MouseDown(object sender, MouseEventArgs e)  
    {  
        if (e.Button == MouseButtons.Left) PanelMouseDownLocation = e.Location;     
    }  
    private void panel1_MouseMove(object sender, MouseEventArgs e)  
    {  
        if (e.Button == MouseButtons.Left)  
        {  
            panel1.Left += e.X - PanelMouseDownLocation.X;  
      
            panel1.Top += e.Y - PanelMouseDownLocation.Y;  
            this.Refresh();  
        }     
    }  
    private void Form1_Paint(object sender, PaintEventArgs e)  
    {  
        if (shadowBmp == null || shadowBmp.Size != this.Size)  
        {  
            shadowBmp?.Dispose();  
            shadowBmp = new Bitmap(this.Width, this.Height, PixelFormat.Format32bppArgb);  
        }  
        foreach (Control control in shadowControls)  
        {  
            using (GraphicsPath gp = new GraphicsPath())  
            {  
                gp.AddRectangle(new Rectangle(control.Location.X, control.Location.Y, control.Size.Width, control.Size.Height));  
                DrawShadowSmooth(gp, 100, 60, shadowBmp);  
            }  
            e.Graphics.DrawImage(shadowBmp, new Point(0, 0));  
        }  
    }  
      
    private static void DrawShadowSmooth(GraphicsPath gp, int intensity, int radius, Bitmap dest)  
    {  
        using (Graphics g = Graphics.FromImage(dest))  
        {  
            g.Clear(Color.Transparent);  
            g.CompositingMode = CompositingMode.SourceCopy;  
            double alpha = 0;  
            double astep = 0;  
            double astepstep = (double)intensity / radius / (radius / 2D);  
            for (int thickness = radius; thickness > 0; thickness--)  
            {  
                using (Pen p = new Pen(Color.FromArgb((int)alpha, 0, 0, 0), thickness))  
                {  
                    p.LineJoin = LineJoin.Round;  
                    g.DrawPath(p, gp);  
                }  
                alpha += astep;  
                astep += astepstep;  
            }  
        }  
    }  
    

    The result:
    56122-113.gif
    Here is a related thread you can refer to.
    Best Regards,
    Daniel Zhang


    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  2. Karen Payne MVP 35,426 Reputation points
    2021-01-13T16:36:34.88+00:00

    Hello @Jo SRM

    For a movable control (any control) see the following Code Project article. The class also allows remember/restore positions. I didn't address the actual panel as it's DevExpress third party library which I don't have but should work fine.

    Example usage

    ControlMoverOrResizer.Init(shadowPanel1);  
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.