Graphics.Clear on a Windows Form Control also clears the control itself - how to prevent this?
Question
I try to draw a custom selection rectangle on a Picturebox, using the method below:
void _drag_UpdateView(bool clearOnly, MouseEventArgs e)
{
System.Diagnostics.Debug.WriteLine("UpdateView");
using (Graphics g = this.i_rendered.CreateGraphics())
{
g.Clear(Color.Transparent);
if (clearOnly)
return;
int px = (_drag_start.X > e.Location.X)?e.Location.X:_drag_start.X;
int py = (_drag_start.Y > e.Location.Y)?e.Location.Y:_drag_start.Y;
if (px < 0)
px = 0;
if (py < 0)
py = 0;
int wx = Math.Abs(e.Location.X-_drag_start.X);
int wy = Math.Abs(e.Location.Y-_drag_start.Y);
g.DrawRectangle(Pens.LightBlue, px, py, wx, wy);
}
}
Whenever I call:
g.Clear(Color.Transparent);
the whole picturebox turns black. However, the rectangle gets drawn over it. If I do not call that method, the rectangles stack on itself, of course. I want to remove the old rectangle and create a new one like this.
Can anyone describe what's wrong?
Solution
Do not paint your control inside any other method than OnPaintBackground
or OnPaint
.
Actually you may need it for performance reasons (your won't refresh the full control, just change something on-the-fly) but it'll make your code much more tricky and you'll always need to do the same job inside the Paint
event too (because it may be called for many other reasons so the output should be the same).
Inside the Paint
you do not even need to use CreateGraphics
, the graphics context is inside the PaintEventArgs
object so change your code to:
void DoPainting(object sender, PaintEventArgs e)
{
// Do your calculations
e.Graphics.DrawRectangle(Pens.LightBlue, px, py, wx, wy);
}
As pointed by @AndersForsgren to use the CreateGraphics
method is not common and usually you do not need to call it (with the exception pointed before and when, for example, you need to perform some calculations based on the graphics like for AutoSize).