在Winforms控件中放置阴影?

vc6uscn9  于 2023-10-23  发布在  其他
关注(0)|答案(6)|浏览(141)

有办法给控件添加阴影吗?
是否有任何控制有这个功能?

aij0ehis

aij0ehis1#

你必须像这样覆盖CreateParams属性:

private const int CS_DROPSHADOW = 0x00020000;
protected override CreateParams CreateParams
{
    get
    {
        // add the drop shadow flag for automatically drawing
        // a drop shadow around the form
        CreateParams cp = base.CreateParams;
        cp.ClassStyle |= CS_DROPSHADOW;
        return cp;
    }
}
nnsrf1az

nnsrf1az2#

这个问题已经存在了6年,需要一个答案。我希望任何需要这样做的人都可以从我的解决方案中推断出任何控件集的答案。我有一个面板,想在每个子控件下面画一个阴影-在这个例子中是一个或多个面板(但是这个解决方案应该对其他控件类型有一些小的代码修改)。
由于一个控件的投影必须绘制在该控件容器的表面上,我们首先向容器的Paint()事件添加一个函数。

Container.Paint += dropShadow;

dropShadow()看起来像这样:

private void dropShadow(object sender, PaintEventArgs e)
    {
        Panel panel = (Panel)sender;
        Color[] shadow = new Color[3];
        shadow[0] = Color.FromArgb(181, 181, 181);
        shadow[1] = Color.FromArgb(195, 195, 195);
        shadow[2] = Color.FromArgb(211, 211, 211);
        Pen pen = new Pen(shadow[0]);
        using (pen)
        {
            foreach (Panel p in panel.Controls.OfType<Panel>())
            {
                Point pt = p.Location;
                pt.Y += p.Height;
                for (var sp = 0; sp < 3; sp++)
                {
                    pen.Color = shadow[sp];
                    e.Graphics.DrawLine(pen, pt.X, pt.Y, pt.X + p.Width - 1, pt.Y);
                    pt.Y++;
                }
            }
        }
    }

显然,你可以从容器的集合中选择不同的控件类型,你可以通过一些小的调整来改变阴影的颜色和深度。

fkaflof6

fkaflof63#

最高的答案实际上会产生一个阴影,但我个人对它并不满意,原因有几个:

  • 它只适用于矩形(当然,WinForms控件都是矩形,但我们可能希望在其他情况下使用它)
  • 更重要的是:它不光滑。它看起来不像其他程序中的其他阴影那样自然。
  • 最后,配置有点烦人。

所以,因为所有这些事情,我最终为我的项目写了我自己的,我想我会在这里分享:

public partial class Form1 : Form
{
    List<Control> shadowControls = new List<Control>();
    Bitmap shadowBmp = null;
    public Form1()
    {
        InitializeComponent();
        shadowControls.Add(panel1);
        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;
            }
        }
    }
}

在这个实现中,所有添加到shadowControls的控件都将使用平滑的阴影绘制。您应该能够对非矩形形状实现此功能,因为生成阴影的主函数需要GraphicsPath。请注意,在将阴影绘制到窗体之前,将阴影绘制到另一个位图是很重要的,因为main函数需要SourceCopy的合成模式才能工作,这意味着如果您不首先将其绘制到另一个表面,则阴影后面的任何内容都将被完全替换,并且透明度方面是无用的。我正在回答10岁的问题,但希望这能帮助到别人!

zhte4eai

zhte4eai4#

如果你可以扩展到使用WPF,我不相信在Windows窗体中有替代方案,因为GDI+的能力有限。

snz8szmq

snz8szmq5#

一种方法是将控件放置在具有以下属性的表布局中:

  • 3列(5 px,100%,5 px)
  • 3行(5 px,100%,5 px)
  • 你的控制
  • 左上角(0,0)
  • columnSpan = 2,rowSpan = 2
  • 0保证金
  • 停靠设置为填充
  • 添加配电盘
  • 设置您的阴影颜色作为背景
  • 行= 1,列= 3
  • 0保证金
  • 停靠设置为填充
  • 添加其他面板
  • 设置您的阴影颜色作为背景
  • 行= 3,列= 1,列跨度= 2
  • 0保证金
  • 停靠设置为填充

这将给予调整外部列和行大小的灵活性。下面是一个快速草图,可以直观地看到设计器中的表布局:
Table Layout Sketch
Table Layout Sketch 2
应用程序中最终结果的实际屏幕截图:
Screenshot

b0zn9rqh

b0zn9rqh6#

这里有一个有争议的观点,你不用代码就可以做到。将主面板的边框样式设置为固定单边框。在它下面创建3个面板,每个面板在每个方向上都大1个像素。3个面板中的每一个都是浅灰色。不完美,但便宜和容易。
panel with pseudo-shadow

相关问题