Graphics.Clear в элементе управления формой Windows также очищает сам элемент управления – как это предотвратить?
Вопрос
Я пытаюсь нарисовать пользовательский прямоугольник выделения в Picturebox, используя метод ниже:
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);
}
}
Всякий раз, когда я звоню:
g.Clear(Color.Transparent);
весь Picturebox становится черным.Однако прямоугольник рисуется поверх него.Если я не вызываю этот метод, прямоугольники, конечно, складываются сами в себя.Я хочу удалить старый прямоугольник и создать такой новый.
Кто-нибудь может описать, что не так?
Решение
Не рисуйте свой элемент управления каким-либо другим методом, кроме OnPaintBackground
или OnPaint
.
На самом деле вам это может понадобиться из соображений производительности (вы не обновите полный контроль, а просто измените что-то на лету), но это сделает ваш код намного сложнее, и вам всегда придется выполнять одну и ту же работу внутри Paint
событие (поскольку оно может быть вызвано по многим другим причинам, поэтому вывод должен быть таким же).
Внутри Paint
вам даже не нужно использовать CreateGraphics
, графический контекст находится внутри PaintEventArgs
объект, поэтому измените свой код на:
void DoPainting(object sender, PaintEventArgs e)
{
// Do your calculations
e.Graphics.DrawRectangle(Pens.LightBlue, px, py, wx, wy);
}
Как указал @AndersForsgren, чтобы использовать CreateGraphics
метод не является распространенным и обычно вам не нужно его вызывать (за исключением, указанным до и когда, например, вам нужно выполнить некоторые вычисления на основе графики, как для AutoSize).