通过最小化窗体绘制透明面板而不会变黑

时间:2019-01-12 08:46:02

标签: c# winforms panel transparency

我正在使用C#在图片框的位图上绘制一个面板。我使用了下面的代码,当我不最小化Form时很好。 当我最小化Form并再次将其最大化到第一个尺寸时,此类绘制的所有面板均显示黑色背景。  我发现,当我将ControlStyles.Opaque更改为诸如“ SupportsTransparentBackColor”之类的其他问题时,该问题将得到解决,但面板将不再透明。

public class ExtendedPanel : Panel
{
    private const int WS_EX_TRANSPARENT = 0x00;
    public ExtendedPanel()
    {
         SetStyle(ControlStyles.Opaque, true);
    }

private int opacity = 1;
[DefaultValue(1)]
public int Opacity
{
    get
    {
        return this.opacity;
    }
    set
    {
        if (value < 0 || value > 100)
            throw new ArgumentException("value must be between 0 and 100");
        this.opacity = value;
    }
}
protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        cp.ExStyle = cp.ExStyle | WS_EX_TRANSPARENT;
        return cp;
    }
}
protected override void OnPaint(PaintEventArgs e)
{
    using (var brush = new SolidBrush(Color.FromArgb(this.opacity * 1 / 100, this.BackColor)))
    {
        e.Graphics.FillRectangle(brush, this.ClientRectangle);
    }
    base.OnPaint(e);
}

}

1 个答案:

答案 0 :(得分:3)

Reza Aghaei已经告诉您实际上是什么导致面板透明性根本无法发挥作用:
WS_EX_TRANSPARENT 已设置为0x00,而不是0x20

一些改善半透明面板外观的建议。

  • 测试面板以设置以下样式

这将防止在Desing-Time和Run-Time上移动面板上的任何工件。

this.SetStyle(ControlStyles.AllPaintingInWmPaint |
              ControlStyles.UserPaint |
              ControlStyles.Opaque, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
this.DoubleBuffered = false;
this.UpdateStyles();
  • 设置不透明度值

如果使用的是 Refresh() ,这将立即更新新的 Opacity 外观。否则,您必须单击“表格”以查看更改。在运行时, Invalidate() (通常)就足够了。

set {
    if (value < 0 || value > 255) throw new ArgumentException("value must be between 0 and 255");
    this.opacity = value;
    if (this.DesignMode) this.FindForm().Refresh();
    this.Invalidate();
}

修改后的测试类:

public class ExtendedPanel : Panel
{
    private const int WS_EX_TRANSPARENT = 0x20;
    public ExtendedPanel()
    {
        this.SetStyle(ControlStyles.AllPaintingInWmPaint |
                      ControlStyles.UserPaint |
                      ControlStyles.Opaque, true);
        this.SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
        this.DoubleBuffered = false;
        this.UpdateStyles();
    }

    private int opacity = 1;

    [DefaultValue(1)]
    public int Opacity
    {
        get => this.opacity;
        set {
            if (value < 0 || value > 255) throw new ArgumentException("value must be between 0 and 255");
            this.opacity = value;
            if (this.DesignMode) this.FindForm().Refresh();
            this.Invalidate();
        }
    }

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle = cp.ExStyle | WS_EX_TRANSPARENT;
            return cp;
        }
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        using (SolidBrush bgbrush = new SolidBrush(Color.FromArgb(this.opacity, this.BackColor)))
        {
            e.Graphics.FillRectangle(bgbrush, this.ClientRectangle);
        }
    }
}