使用alpha叠加组件,在其下重新绘制控件时重绘

时间:2011-04-23 22:31:43

标签: c# .net winforms alpha

我创建了一个自定义控件,我想用它来覆盖部分表单,并根据需要显示状态信息。它应该显示文本并具有背景颜色,具体取决于信息的类型。这是仍然不完整的代码。

public partial class StatusPanel : UserControl
{
    public enum PanelStyle
    {
        Info,
        Warning,
        Error
    }

    public PanelStyle Style { get; set; }

    public StatusPanel()
    {
        InitializeComponent();

        this.imgGreen = new Bitmap(256, 256, PixelFormat.Format32bppArgb);
        using(Graphics g = Graphics.FromImage(this.imgGreen))
        {
            g.Clear(Color.Transparent);
            Brush bg = new SolidBrush(Color.FromArgb(200, Color.Green));
            g.FillRectangle(bg, 0, 0, 256, 256);
        }

        this.imgYellow = new Bitmap(256, 256, PixelFormat.Format32bppArgb);
        using(Graphics g = Graphics.FromImage(this.imgYellow))
        {
            g.Clear(Color.Transparent);
            Brush bg = new SolidBrush(Color.FromArgb(10, Color.Yellow));
            g.FillRectangle(bg, 0, 0, 256, 256);
        }
    }

    protected readonly Font font = new Font("Arial", 12.0F);

    protected readonly Brush textBrush = new SolidBrush(Color.Black);

    protected readonly Image imgGreen;

    protected readonly Image imgYellow;

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

    protected override void OnPaintBackground(PaintEventArgs e)
    {
        // do not draw background
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
        e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
        e.Graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
        e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

        Image img = GetImage();

        e.Graphics.DrawImage(img, 0, 0, this.Width, this.Height);

        e.Graphics.DrawString("ABC", this.font, this.textBrush, 1.0F, 1.0F);
    }

    protected Image GetImage()
    {
        return (this.Style == PanelStyle.Info) ? this.imgGreen : this.imgYellow;
    }
}

这很好用。但是当我在表格上放置一些按钮并且其中一个按钮控制在它们前面时,当鼠标移过按钮并且高亮效果重绘它们时,它们将“过度绘制”。

我的组件如何通知它需要重绘,因为底层控件已重新绘制?

1 个答案:

答案 0 :(得分:1)

Parent.Control下的所有控件注册一个paint-handler,并注册一个注册你的paint-handler

Parent.ControlAdded处理程序

类似的东西:

private void myDummyUserControl_Load(object sender, EventArgs e)
{
    var uc = (DummyUserControl)sender;
    uc.Parent.ControlAdded += new ControlEventHandler(Parent_ControlAdded);
    foreach (Control c in uc.Parent.Controls)
    {
        if (uc == c)
            continue;
        c.Paint += new PaintEventHandler(c_Paint);
    }
}

void c_Paint(object sender, PaintEventArgs e)
{
    //checks & paint stuff here
}

void Parent_ControlAdded(object sender, ControlEventArgs e)
{
    e.Control.Paint += new PaintEventHandler(c_Paint);
}

//修改

不确定是否需要使用递归来查看子控件的树,并且还需要在这些上添加处理程序...