trycatch
trycatch

Reputation: 578

Trigger repaint on custom control after being offscreen/obscured?

I've got a few custom controls that are covered in images, and if they get dragged off screen and back on, the image isn't repainted properly. I've got on paint overriden for these various controls, and they seem to work fine, other than they don't get drawn properly if dragged off screen on and on again. Anyone know why this might happen and/or a solution?

Edit: there seem to be issues with some of them even if the dialog is simply moved resized too fast, rather than just if it's taken off screen. They start looking like they've been drawn on top of themselves. Which kind of makes sense, but I can't figure out how to cure it.

Edit 2: These are custom buttons with fourstates (hover, click, normal, disabled), so I don't think the container thing is the issue I don't think..? The OnPaint code is:



private void CQPButton_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.Clear(BackColor);

    if (BackgroundImage != null)
        e.Graphics.DrawImage(BackgroundImage, e.ClipRectangle);

    if (Image != null)
    {
        RectangleF rect = new RectangleF();
        rect.X = (float)((e.ClipRectangle.Width - Image.Size.Width) / 2.0);
        rect.Y = (float)((e.ClipRectangle.Height - Image.Size.Height) / 2.0);
        rect.Width = Image.Width;
        rect.Height = Image.Height;
        e.Graphics.DrawImage(Image, rect);
    }

    if (Text != null)
    {
        SizeF size = e.Graphics.MeasureString(this.Text, this.Font);

        // Center the text inside the client area of the PictureButton.
        e.Graphics.DrawString(this.Text,
            this.Font,
            new SolidBrush(this.ForeColor),
            (this.ClientSize.Width - size.Width) / 2,
            (this.ClientSize.Height - size.Height) / 2);
    }

}

I've tried forcing repaint on various events, LocationChanged and Move to try and deal with the resize issue, ClientSizeChanged to try and deal with when they're off screen, and nothing is sticking. I don't know what I'm missing...

Upvotes: 0

Views: 355

Answers (1)

Hans Passant
Hans Passant

Reputation: 941237

I completely changed my answer after seeing the code snippet. It has a bug:

    RectangleF rect = new RectangleF();
    rect.X = (float)((e.ClipRectangle.Width - Image.Size.Width) / 2.0);
    rect.Y = (float)((e.ClipRectangle.Height - Image.Size.Height) / 2.0);

Using e.ClipRectangle is incorrect here, it is a value that always changes, depending on what part of the control needs to be repainted. And yes, it changes most when you resize the control or drag it partially off the screen. You need to use the actual size of your control:

    rect.X = (float)((this.ClientSize.Width - Image.Size.Width) / 2.0);
    rect.Y = (float)((this.ClientSize.Height - Image.Size.Height) / 2.0);

Upvotes: 3

Related Questions