简体   繁体   English

在Graphics.DrawLine C#Visual Studio中画线时出错

[英]Error when drawing line in Graphics.DrawLine C# Visual Studio

private void Form1_Paint(object sender, PaintEventArgs e)
    {
        Graphics l = e.Graphics;
        Pen p = new Pen(Color.Black, 1);
        float angle = 0;
        float len = 100;
        PointF ori = new PointF(Width/2, 0);    
        PointF bob = new PointF(Width/2, len);
        while(true)
        {

            bob.X = ori.X + len * (float)Math.Sin(angle);
            bob.Y = ori.Y + len * (float)Math.Cos(angle);
            angle += 0.001F;
            l.DrawLine(p, ori.X, ori.Y, bob.X, bob.Y);
            l.DrawEllipse(p, bob.X - 15, bob.Y, 30, 30);
            if(angle == 360)
            {
                break;
            }
            l.Dispose();
        } 
    }

The error line is l.DrawLine(p, ori.X, ori.Y, bob.X, bob.Y). 错误行是l.DrawLine(p,ori.X,ori.Y,bob.X,bob.Y)。 Error type: System.ArgumentException. 错误类型:System.ArgumentException。 Error Message: Parameter is not valid. 错误消息:参数无效。

At first I thought the issue was with the floats but the DrawLine allows for such datatypes. 起初,我认为问题出在浮子上,但是DrawLine允许使用此类数据类型。 It loops through once the error seems to occur when angle>0. 当角度> 0时似乎发生错误时,它将循环通过。 Its magnitude doesn't seem to be the issue. 它的大小似乎不是问题。 Any help would be much appreciated. 任何帮助将非常感激。 Thanks in advance. 提前致谢。 [UPDATE] Error seems to be with the l.Dispose [更新]错误似乎与l.Dispose有关

The problem is in the wrong Dispose call: 问题出在错误的Dispose调用中:

private void Form1_Paint(object sender, PaintEventArgs e)
{
    Graphics l = e.Graphics;

    // Pen is IDisposable, that's why why wrap it into "using": it's you who created it 
    using (Pen p = new Pen(Color.Black, 1)) {
      float angle = 0;
      float len = 100;
      PointF ori = new PointF(Width/2, 0);    
      PointF bob = new PointF(Width/2, len);

      while(true)
      {
        bob.X = ori.X + len * (float)Math.Sin(angle);
        bob.Y = ori.Y + len * (float)Math.Cos(angle);
        angle += 0.001F;

        l.DrawLine(p, ori.X, ori.Y, bob.X, bob.Y);
        l.DrawEllipse(p, bob.X - 15, bob.Y, 30, 30);

        // angle is float, that's why == is not recommended:
        // (you can well have 359.99999999999999) and thus == will never be true
        if (angle >= 360) 
            break;

        // l.Dispose(); // <- Wrong: it's not you who've created it
                        // (let system Dispose it) 
      } 
    }
}

As an enhancement to @Dmitry's answer, I can offer this advice: 作为对@Dmitry答案的增强,我可以提供以下建议:

As a general rule, you shouldn't call Dispose on an object that you do not control the lifetime of. 通常,您不应在不受生命周期控制的对象上调用Dispose You are getting an existing Graphics instance from the Paint event. 您正在从Paint事件中获取现有的Graphics实例。 The control that raised the Paint event is what created that Graphics object, so it is responsible for calling Dispose on it when it is done with it, not you. 引发Paint事件的控件是创建该Graphics对象的对象,因此它负责在完成操作后调用Dispose ,而不是您自己。

When you call Dispose on an object that you don't control, you effectively "rip the rug out from under" that code. 当您在不受控制的对象上调用Dispose时,可以有效地将代码“从底层剥离”。 This is bad, because that code could be expecting the instance to still be alive so that it can perform other operations on it. 这很糟糕,因为该代码可能期望该实例仍然处于活动状态,以便可以对该实例执行其他操作。 By disposing it, you don't give it that chance. 通过处理它,您不会给它机会。

You are doing the correct thing with your Pen instance, p , though. 但是,您正在使用Pen实例p做正确的事情。 You create it during the using statement, so you are responsible for it. 您在using语句期间创建它,因此您对此负有责任。 The Using handles that by automatically calling Dispose when execution leave the block. Using通过在执行时离开该块自动调用Dispose该问题。

If you had created the Graphics instance yourself, with something like Graphics.FromImage`, then you would be responsible for cleaning it up. 如果您instance yourself, with something like Graphics.FromImage`之类的instance yourself, with something like创建了Graphics instance yourself, with something like那么您将负责清理它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM