【问题标题】:Drawing lines with GDI - Invalidate() / onPaint problem使用 GDI 绘制线条 - Invalidate() / onPaint 问题
【发布时间】:2011-11-18 15:07:59
【问题描述】:

我一直在学习如何使用 GDI,但很难理解 Invalidate() 和覆盖 onPaint 事件的工作原理,并且似乎在循环往复。

我有以下代码

private void DrawLine()
{
     System.Drawing.Pen myPen = new System.Drawing.Pen(System.Drawing.Color.Red);
     System.Drawing.Graphics formGraphics;
     formGraphics = this.CreateGraphics();
     formGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
     formGraphics.DrawLine(myPen, mouseDown.X, mouseDown.Y, mouseUp.X, mouseUp.Y);
     myPen.Dispose();
     formGraphics.Dispose();
}

protected override void OnPaint(PaintEventArgs e)
{
     DrawLine();
}

private void Form1_MouseDown(object sender, MouseEventArgs e)
{
     mouseDown = e.Location;

}

private void Form1_MouseUp(object sender, MouseEventArgs e)
{
     mouseUp = e.Location;           
}

但是,我可以让我刚刚绘制的线条出现的唯一方法是手动调用 Invalidate(),当我这样做时,它会清除之前的所有线条。谁能告诉我这个问题在哪里?

【问题讨论】:

    标签: c# gdi


    【解决方案1】:

    改成这样:

    Bitmap bmp = new Bitmap(256, 256);
    
    protected override void OnPaint(PaintEventArgs e)
    {
      e.Graphics.DrawImage(bmp, new Point(0, 0));
    }
    
    private void Form1_MouseDown(object sender, MouseEventArgs e)
    {
      mouseDown = e.Location;
    }
    
    private void Form1_MouseUp(object sender, MouseEventArgs e)
    {
       mouseUp = e.Location;
       using (Graphics g = Graphics.FromImage(bmp))
       {
         g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
         g.DrawLine(Pens.Red, mouseDown.X, mouseDown.Y, mouseUp.X, mouseUp.Y);
       }
       this.Invalidate();           
    }
    

    OnPaint 方法提供了用于绘制的图形画布。事实上,您很少需要自己调用 CreateGraphics。 MouseUp 上的 Invalidate() 调用告诉您的控件调用 OnPaint 事件。

    【讨论】:

    • 感谢您的回答,它工作得很好,但是当我画一条线时,屏幕上的任何先前的线都会被删除。我还有什么遗漏的吗?
    • @GrandMasterFlush 你需要一个位图。我一会儿再更新。
    • 非常感谢您抽出宝贵的时间发帖,我整个上午都在转圈。这说明了很多。
    【解决方案2】:

    让你的 DrawLine 带有一个 Graphics 参数:

    public void DrawLine(Graphics g) { 
    //...
    }
    

    在 OnPaint 中,利用来自 e: 的图形

    protected override void OnPaint(PaintEventArgs e)
    {
         DrawLine(e.Graphics);
    }
    

    在 MouseUp 中再次使用表单背景图像中的 Graphics 对象调用 DrawLine:

    private void Form1_MouseUp(object sender, MouseEventArgs e)
    {
         mouseUp = e.Location;   
         DrawLine(Graphics.FromImage(BackgroundImage));  
         Invalidate();
    }
    

    添加 MouseMove 方法:

    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
         mouseUp = e.Location;   
         Invalidate();
    }
    

    可选,为清楚起见,将 mouseDown 重命名为 StartPoint 和 mouseUp - EndPoint。

    【讨论】:

      猜你喜欢
      • 2011-06-01
      • 1970-01-01
      • 2011-04-01
      • 2015-03-23
      • 1970-01-01
      • 1970-01-01
      • 2016-11-10
      • 2011-02-07
      • 1970-01-01
      相关资源
      最近更新 更多