【问题标题】:draw and remove a line with gdi+用 gdi+ 画线和删除线
【发布时间】:2012-08-05 13:13:24
【问题描述】:

我拥有使用 GDI+ 的复杂绘图代码,它在用户控件上绘制类似于图表的东西。 如果用户在按住控件的情况下单击,则应显示虚线样式的垂直标记线。

现在我正在寻找一种方法来扩展绘图代码,而无需触及复杂的绘图代码。

我创建了一个标记类,它附加到用户控件的鼠标向上事件。 在事件处理程序中,对(ModifierKeys == Keys.Control) 的检查已完成。

如果用户按住控制键并用鼠标左键单击,则以用户控件的Graphics 对象作为参数调用标记类的绘制方法。

当前的行为是每次单击都会绘制一条新线,但应删除该线并绘制一条新线。

我怎样才能删除画线?

是否必须重新绘制用户控件的完整内容?

【问题讨论】:

    标签: c# winforms c#-4.0 gdi+


    【解决方案1】:

    您无法删除绘制的线,因为无法恢复底层图形。

    你可以做的是:

    • 重绘整个图形(不带线)

    • 在顶部堆叠第二个透明用户控件并使用它来显示该行。需要时将其移除和绘制。

    【讨论】:

      【解决方案2】:

      这里的答案显然是肯定的。使用 GDI+,您只需直接在位图缓冲区上绘图,因此如果您想撤消先前的绘图操作,您可以执行以下操作之一(取决于问题的复杂性和性能):

      • 恢复位图缓冲区中已更改的字节
      • 重新加载绘图位图的先前状态

      一个简单的解决方案是使用 2 个位图(类似的东西通常称为双缓冲)。一个当前显示(并包含最终状态),一个仅用于预览。预览版始终是第一个版的副本 - 只是带有当前修改。

      这个简单实现的基本算法:

      • 从两个位图开始(空白但大小相同)[命名为 A 和 B]
      • 如果用户画一条线,总是在 B 中复制位图 A 并在 B 上绘制 - 显示 B
      • 如果用户完成该行,则在 A 中复制 B 并再次 - 显示 B

      所以总是显示预览位图,它只是原始位图的修改。

      这是一个 C# 中的示例编程代码(假设所有事件都已连接,并且预览位图 B 是图片框本身(此处仅命名为 pictureBox1):

      Bitmap bmp;
      bool isDrawing;
      Point previous;
      
      void pictureBox1_MouseDown(object sender, MouseEventArgs e)
      {
          isDrawing = true;
          previous = e.Location;
      }
      
      void pictureBox1_MouseUp(object sender, MouseEventArgs e)
      {
          isDrawing = false;
      }
      
      void pictureBox1_MouseMove(object sender, MouseEventArgs e)
      {
          if (isDrawing)
          {
              using (Graphics g = Graphics.FromImage(bmp))
              {
                  double wf = (double)bmp.Width / (double)pictureBox1.Width;
                  double hf = (double)bmp.Height / (double)pictureBox1.Height;
                  g.ScaleTransform((float)wf, (float)hf);
                  g.DrawLine(Pens.Black, e.Location, previous);
              }
      
              pictureBox1.Refresh();
              previous = e.Location;
          }
      }
      

      此代码将执行所有操作,只需按下鼠标左键即可显示从一个点到另一个点的直线。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-12-06
        • 2011-05-14
        • 2016-07-05
        • 2011-11-04
        • 1970-01-01
        • 1970-01-01
        • 2017-09-01
        • 1970-01-01
        相关资源
        最近更新 更多