清除 Windows 窗体中的 DrawRectangle

发布于 2024-07-23 12:44:49 字数 263 浏览 6 评论 0原文

我正在绘制一个矩形,休眠了几毫秒——然后我想清除该矩形,但我不知道如何清除。 (该矩形位于图形上方,因此我不能简单地用另一个矩形覆盖它)

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

I am drawing a rectangle, sleeping for a few milliseconds--then I want to clear the rectangle, but I can't figure out how. (The rectangle is sitting over a graphic so I can't simply cover it up with another rectangle)

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

GRAY°灰色天空 2024-07-30 12:44:49

我遇到了同样的问题,并通过在主窗体上绘制一个额外的面板来解决它,并根据需要显示/隐藏、调整大小和位置。

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

I had the same problem and resolved it with an extra panel drawn on the main form and shown/hidden, sized and positioned as necessary.

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

Then when rectangle is not necessary anymore, just hide it by calling:

box.Visible = false;

The panel class is made with transparency to ensure that overlay graphics does not hide other content of the window.

  [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;
      }
    }
  }
风月客 2024-07-30 12:44:49

您需要重新绘制图形(或至少是矩形下方的部分)。 如果这是图片框或类似内容,请使用 Invaldiate() 强制重绘。

You need to redraw the graphic (or at least the part of it under the rectangle). If this is a picture box or something similar, use Invaldiate() to force a repaint.

浪菊怪哟 2024-07-30 12:44:49

如果矩形完全位于图形上方,您应该能够重新绘制或刷新底层图形。 如果不是,您将需要使用背景颜色重新绘制矩形,然后刷新底层图形。

If the rectangle is sitting completely over the graphic you should be able to just redraw or refresh the underlying graphic. If it is not, you will need to redraw the rectangle using the background color, and then refresh the underlying graphic.

゛时过境迁 2024-07-30 12:44:49

我想在绘制矩形之前应该将原始数据从表面复制到临时位图中,然后将位图绘制回原位。

更新

已经有一个被接受的答案,但我想无论如何我都可以分享一个代码示例。 该函数在给定控件上以红色绘制给定矩形,并在 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;
}

I guess it should work to copy the original data from the surface into a temporary bitmap before drawing the rectangle, and then draw the bitmap back in place.

Update

There is already an accepted answer, but I thought I could share a code sample anyway. This one draws the given rectangle in red on the given control, and restores the area after 500 ms.

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文