Компонент наложения с альфа-каналом, перерисовывается, когда элементы управления под ним перерисовываются - PullRequest
1 голос
/ 24 апреля 2011

Я создал пользовательский элемент управления, который хочу использовать для наложения части моей формы на информацию о состоянии по требованию. Он должен отображать текст и иметь цвет фона в зависимости от типа информации. Вот еще неполный код.

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 Ответ

1 голос
/ 24 апреля 2011

зарегистрируйте обработчик рисования для всех элементов управления в Parent.Control и обработчик для 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);
}

// edit

не уверен, нужно ли вам использовать рекурсию для перехода по дереву дочерних элементов управления и нужно ли добавлять к ним и обработчики ...

...