Очистка DrawRectangle в Windows Forms

Я рисую прямоугольник, сплю несколько миллисекунд, затем хочу очистить прямоугольник, но не могу понять, как это сделать. (Прямоугольник располагается над графикой, поэтому я не могу просто закрыть его другим прямоугольником)

                graphics.DrawRectangle(p, innerRectangle)
                System.Threading.Thread.Sleep(75)
                Next I want to clear the rectange...

4 ответа

Решение

Вам нужно перерисовать рисунок (или хотя бы его часть под прямоугольником). Если это графическое окно или что-то подобное, используйте Invaldiate(), чтобы вызвать перерисовку.

Если прямоугольник полностью расположен над графикой, вы сможете просто перерисовать или обновить базовую графику. Если это не так, вам нужно будет перерисовать прямоугольник, используя цвет фона, а затем обновить базовый рисунок.

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

Обновить

Уже есть принятый ответ, но я подумал, что смог бы поделиться примером кода в любом случае. Этот рисует данный прямоугольник красным на данном элементе управления и восстанавливает область через 500 мс.

public void ShowRectangleBriefly(Control ctl, Rectangle rect)
{
    Image toRestore = DrawRectangle(ctl, rect);
    ThreadPool.QueueUserWorkItem((WaitCallback)delegate
    {
        Thread.Sleep(500);
        this.Invoke(new Action<Control, Rectangle, Image>(RestoreBackground), ctl, rect, toRestore);
    });
}

private void RestoreBackground(Control ctl, Rectangle rect, Image image)
{
    using (Graphics g = ctl.CreateGraphics())
    {
        g.DrawImage(image, rect.Top, rect.Left, image.Width, image.Height);
    }
    image.Dispose();
}

private Image DrawRectangle(Control ctl, Rectangle rect)
{
    Bitmap tempBmp = new Bitmap(rect.Width + 1, rect.Height + 1);
    using (Graphics g = Graphics.FromImage(tempBmp))
    {
        g.CopyFromScreen(ctl.PointToScreen(new Point(rect.Top, rect.Left)), new Point(0, 0), tempBmp.Size);
    }

    using (Graphics g = this.CreateGraphics())
    {
        g.DrawRectangle(Pens.Red, rect);
    }
    return tempBmp;
}

У меня была та же проблема, и я решил ее с помощью дополнительной панели, нарисованной на главной форме и показанной / скрытой, с размерами и позиционированием по мере необходимости.

SelectionBox box = new SelectionBox();
box.Location = location;
box.Size = size;
box.Visible = true;

Затем, когда прямоугольник больше не нужен, просто спрячьте его, вызвав:

box.Visible = false;

Класс панели выполнен с прозрачностью, чтобы оверлейная графика не скрывала другое содержимое окна.

  [System.ComponentModel.DesignerCategory("Code")]
  public class SelectionBox : Panel
  {
    protected override void OnPaint(PaintEventArgs e)
    {
      const int penWidth = 2;
      int offset = penWidth - 1;
      using (Pen pen = new Pen(Color.Red, 2))
        e.Graphics.DrawRectangle(pen, offset, offset, 
          ClientSize.Width - offset - 1, ClientSize.Height - offset - 1);
    }

    protected override CreateParams CreateParams
    {
      get
      {
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x00000020; // WS_EX_TRANSPARENT
        return cp;
      }
    }
  }
Другие вопросы по тегам