C# 如何绘制更新线

C# 如何绘制更新线,c#,drawing,line,C#,Drawing,Line,我的目标很简单。想象一下打开MSPaint,单击线条工具,按住鼠标,然后将其拖动。它锚定您单击鼠标的起始坐标,并不断绘制和重画一条线到您的当前位置 除了我尝试在C#中这样做,没有我希望的那么好 [DllImport("user32.dll")] static extern IntPtr GetDC(IntPtr hWnd); [DllImport("User32.dll")] static extern int ReleaseDC(IntPtr hwnd, IntPtr dc); protec

我的目标很简单。想象一下打开MSPaint,单击线条工具,按住鼠标,然后将其拖动。它锚定您单击鼠标的起始坐标,并不断绘制和重画一条线到您的当前位置

除了我尝试在C#中这样做,没有我希望的那么好

[DllImport("user32.dll")]
static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("User32.dll")]
static extern int ReleaseDC(IntPtr hwnd, IntPtr dc);

protected override void OnPaint(PaintEventArgs e)
{
    endingPoint = GetMouseCoords();
    DrawLine(startingPoint, endingPoint);
}

private void DrawLine(Point startingCoords, Point endingCoords)
{
    IntPtr desktop = GetDC(IntPtr.Zero);
    Pen pen = new Pen(Brushes.Red, 3);
    using (Graphics g = Graphics.FromHdc(desktop))
    {
        g.DrawLine(pen, startingCoords.X, startingCoords.Y, endingCoords.X, endingCoords.Y);
        g.Dispose();
    }
    ReleaseDC(IntPtr.Zero, desktop);
}
用这种方法,我只画了一次线。但是,如果我将DrawLine()移动到一个更静态的事件(如MouseUp),它将绘制它,然后在大约四分之一秒后消失

在这里实现目标的最佳方式是什么?


我认为,无论使用什么事件使线条消失,我都希望首先将线条的绘图附加到其中。

您需要有两个绘图调用:

  • 使用
    someControls.CreateGraphics

  • 另一个用于持久化行,在
    鼠标中触发,其中

    • 您存储坐标并
    • 在画布控件上调用
      Invalidate
      ,然后
    • 使用画布的
      e.Graphics
      对象绘制画布的
      Paint
      事件
下面是一个简单的示例代码:

List<Point> allPoints = new List<Point>();
Point mDown = Point.Empty;

private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
    mDown = e.Location;
}

private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
    allPoints.Add(e.Location);
    pictureBox1.Invalidate();
}

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button.HasFlag(MouseButtons.Left))
    {
        pictureBox1.Refresh();
        using (Graphics G = pictureBox1.CreateGraphics())
            G.DrawLine(Pens.Red, mDown, e.Location);
    }
}

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    if (allPoints.Count > 1) e.Graphics.DrawLines(Pens.Black, allPoints.ToArray());
}
List allPoints=new List();
Point mDown=Point.Empty;
私有void pictureBox1\u MouseDown(对象发送方,MouseEventArgs e)
{
mDown=e.位置;
}
私有无效图片box1u MouseUp(对象发送器,MouseEventArgs e)
{
所有点。添加(如位置);
pictureBox1.Invalidate();
}
私有void pictureBox1\u MouseMove(对象发送方,MouseEventArgs e)
{
if(例如按钮HasFlag(鼠标按钮左))
{
pictureBox1.Refresh();
使用(Graphics G=pictureBox1.CreateGraphics())
G.抽绳(红色、向下、例如位置);
}
}
私有void pictureBox1_Paint(对象发送方,PaintEventArgs e)
{
如果(allPoints.Count>1)e.Graphics.DrawLines(Pens.Black,allPoints.ToArray());
}
请注意,这将使用
PictureBox
作为画布控件。它是用于这种交互的控件。你的代码似乎在桌面上绘制,而桌面不属于你。以持久的方式绘制它与您使用/任何绘画应用程序所做的不同

还要注意,我的示例存储了一个点列表,并将它们绘制为一条非闭合多段线。要绘制它们,请将它们关闭交换
绘制线
以绘制
绘制多边形
!若要绘制多条此类多段线或多边形,需要

  • …决定它的用户界面,可能只在按下控制键时添加线段点,否则完成当前多段线
  • 将点存储在
    列表>

还请注意,这是一个罕见的例子,其中需要使用
控件.CreateGraphics
,实际上,当用户移动鼠标时,您需要一个非持久的绘图

大多数其他情况下Winforms graphics基本规则#1适用:


切勿使用
控件。CreateGraphics
!切勿尝试缓存
图形
对象!使用
Graphics g=Graphics.FromImage(bmp)
或在控件的
Paint
事件中,使用
e.Graphics
参数将bmp
绘制到
位图中。

那么您是否尝试在桌面上绘制?为什么?谢谢你。你的解决方案不是我想要的,但足以为我指明正确的方向。我只是在桌面上画画,因为我不知道有更好的方法。此后,我在桌面上方的最大化透明窗体中添加了一个pictureBox。