用gdi +绘制并删除一条线

时间:2012-08-05 13:13:25

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

我拥有GDI +的复杂绘图代码,它在用户控件上绘制了类似图表的内容。 如果用户在按下控件的情况下单击,则应显示破折号样式的垂直标记线。

现在我想方设法扩展绘图代码而不触及复杂的绘图代码。

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

如果用户持有控制键并使用鼠标左键单击,则使用usercontrol的Graphics对象作为参数调用标记类的draw方法。

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

如何擦除画线?

我是否需要重绘用户控件的comlete内容?

2 个答案:

答案 0 :(得分:3)

您无法删除绘制的线条,因为无法恢复基础图形。

你能做的是:

  • 重绘整个图表(不带线条)

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

答案 1 :(得分:1)

答案显然是肯定的。使用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;
    }
}

只需按下鼠标左键,此代码即可显示从一个点到另一个点的直线绘制。