Очистка DrawRectangle в Windows Forms - PullRequest
5 голосов
/ 11 июня 2009

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

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

Ответы [ 4 ]

5 голосов
/ 11 июня 2009

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

2 голосов
/ 11 июня 2009

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

2 голосов
/ 11 июня 2009

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

Обновление

Уже есть принятый ответ, но я подумал, что смог бы поделиться примером кода в любом случае. Этот рисует данный прямоугольник красным на данном элементе управления и восстанавливает область через 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;
}
1 голос
/ 08 апреля 2017

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

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;
      }
    }
  }
...