【问题标题】:Clearing DrawRectangle in Windows Forms在 Windows 窗体中清除 DrawRectangle
【发布时间】:2010-11-02 06:11:04
【问题描述】:

我正在绘制一个矩形,睡了几毫秒——然后我想清除矩形,但我不知道怎么做。 (矩形位于图形上方,所以我不能简单地用另一个矩形覆盖它)

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

【问题讨论】:

    标签: .net vb.net graphics drawrectangle


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

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

        更新

        已经有一个公认的答案,但我想我还是可以分享一个代码示例。这个在给定控件上用红色绘制给定矩形,并在 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;
        }
        

        【讨论】:

          【解决方案4】:

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

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

          【讨论】:

          • 请注意,在这种情况下,覆盖面板会拦截鼠标点击,因此您应该将所有相关事件转发到底层面板。
          猜你喜欢
          • 1970-01-01
          • 2011-02-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-18
          • 1970-01-01
          相关资源
          最近更新 更多