简体   繁体   English

System.ArgumentException:参数无效。 GraphicsPath.AddString

[英]System.ArgumentException: Parameter is not valid. GraphicsPath.AddString

So I've been having this issue when debugging, I get an Access Violation, but when I run without the Debugger, I get an Error that tells me that A Parameter is invalid. 因此,在调试时遇到了这个问题,但是我遇到了访问冲突,但是当我在没有调试器的情况下运行时,出现了一个错误,告诉我参数无效。 It lead me to path.AddString(...); 它带我到path.AddString(...); Any reason as to why? 有什么理由吗? Honestly, all Parameters are correct, else the compiler would catch it. 老实说,所有参数都是正确的,否则编译器会捕获它。 This is making me angry. 这让我很生气。

        protected override void OnPaint( PaintEventArgs e )
        {
            Graphics g = e.Graphics;
            if ( !extended )
            {
                setColor ( );
                g.FillRectangle ( new SolidBrush ( currColor ), this.ClientRectangle );
            }
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;

            string szbuf = Program.AppName;
            SolidBrush brushWhite = new SolidBrush ( Color.White );
            g.FillRectangle ( brushWhite, 0, 0,
            this.ClientSize.Width, this.ClientSize.Height );

            FontFamily fontFamily = this.Font.FontFamily;
            StringFormat strformat = StringFormat.GenericDefault;
            SolidBrush brush = new SolidBrush ( Color.FromArgb ( 255, 255, 255 ) );

            SizeF sz = g.MeasureString(szbuf, this.Font);
            int w = ( ( this.Width / 2 ) - ( ( int ) sz.Width / 2 ) );
            int h = 10;
            GraphicsPath path = new GraphicsPath ( );
            float emSize = g.DpiY * this.Font.Size / 72;
            path.AddString ( szbuf, fontFamily, 0, 48f, new Point ( w, h ), strformat);

            for ( int i = 1; i < 8; ++i )
            {
                Pen pen = new Pen ( getColor ( ), i ); //Color.FromArgb ( 32, 0, 128,  192 ), i );
                pen.LineJoin = LineJoin.Round;
                g.DrawPath ( pen, path );
                pen.Dispose ( );
            }

            g.FillPath ( brush, path );

            fontFamily.Dispose ( );
            path.Dispose ( );
            brush.Dispose ( );
            g.Dispose ( );
        }

With this line: 用这行:

fontFamily.Dispose();

You're disposing this.Font.FontFamily object. 您正在处理this.Font.FontFamily对象。 Control will be in an invalid state and next call to Paint will fail. Control将处于无效状态,并且对Paint下一次调用将失败。 You're also disposing Graphics object, do not do it because it may be used after your function. 您还正在布置Graphics对象,请不要这样做,因为它可能在函数之后使用。

In general you have to dispose only objects you created , nothing more and nothing less (creator owns responsibility to dispose that objects). 通常,您只需要处置创建的对象 ,仅此而已(创建者负责处置这些对象)。 Compiler can't catch this kind of errors (unless you run a static code analysis) because it's a run-time error caused by program execution path. 编译器无法捕获此类错误(除非您运行静态代码分析),因为它是由程序执行路径引起的运行时错误。 If you're lucky you'll have an exception ( ArgumentException because you're passing an invalid argument: a disposed font). 如果幸运的话,您将有一个异常( ArgumentException因为您传递了无效的参数:已处置的字体)。

Moreover you don't need to call Dispose() explicitly, it's more safe to use using statement (it'll work also in case of exceptions). 而且,您不需要显式调用Dispose() ,使用using语句更安全(在发生异常的情况下也可以使用)。 Let me refactor little bit your code : 让我重构一下您的代码

protected override void OnPaint(PaintEventArgs e)
{
    Graphics g = e.Graphics;
    if (!extended)
    {
        setColor();
        using (var backgroundBrush = new SolidBrush(currColor))
        {
            g.FillRectangle(backgroundBrush, this.ClientRectangle);
        }
    }

    g.SmoothingMode = SmoothingMode.AntiAlias;
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;

    string szbuf = Program.AppName;

    g.FillRectangle(Brushes.White, 0, 0,
        this.ClientSize.Width, this.ClientSize.Height);

    StringFormat strformat = StringFormat.GenericDefault;

    SizeF sz = g.MeasureString(szbuf, this.Font);
    int w = ((this.Width / 2) - ((int)sz.Width / 2));
    int h = 10;

    using (var path = new GraphicsPath())
    {
        float emSize = g.DpiY * this.Font.Size / 72;
        path.AddString(szbuf, Font.FontFamily, 0, 48f, new Point(w, h), strformat);

        for (int i = 1; i < 8; ++i)
        {
            using (var pen = new Pen(getColor(), i))
            {
                pen.LineJoin = LineJoin.Round;
                g.DrawPath(pen, path);
            }
        }

        g.FillPath(Brushes.White, path);
    }
}

Please note that to create resources for each paint isn't efficient (allowed but very slow). 请注意,为每种绘画创建资源效率不高(允许但很慢)。 You should reuse them as much as possible (for example using a dictionary). 您应该尽可能地重用它们(例如,使用字典)。 Moreover for constant colors it's better to use predefined brushes (for example Brushes.White , do not dispose them). 此外,为获得恒定的颜色,最好使用预定义的画笔(例如, Brushes.White ,请勿丢弃它们)。 Let me show a very naive implementation (easy to extend to cache both Pen and SolidBrush ): 让我展示一个非常幼稚的实现(易于扩展以缓存PenSolidBrush ):

private Dictionary<Color, SolidBrush> _solidBrushes;
private SolidBrush GetSolidBrush(Color color)
{
    if (_solidBrushes == null)
         _solidBrushes = new Dictionary<Color, SolidBrush>();

    if (!_solidBrushes.ContainsKey(color))
        _solidBrushes.Add(color, new SolidBrush(color));

    return _solidBrushes[color];
}

Then it'll be used like this: 然后它将像这样使用:

if (!extended)
{
    setColor();
    g.FillRectangle(GetSolidBrush(currColor), this.ClientRectangle);
}

暂无
暂无

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

相关问题 System.ArgumentException:参数无效。 在C#中 - System.ArgumentException: Parameter is not valid. in C# System.ArgumentException:&#39;参数无效。 (showDialog错误) - System.ArgumentException: 'Parameter is not valid.' (showDialog error) System.ArgumentException:参数无效 - System.ArgumentException: Parameter is not valid C#System.ArgumentException:参数无效。 在System.Drawing.Bitmap..ctor(Stream stream) - C# System.ArgumentException: Parameter is not valid. at System.Drawing.Bitmap..ctor(Stream stream) Windows窗体:“ System.ArgumentException:参数无效。”来自系统堆栈 - Windows Forms: “System.ArgumentException: Parameter is not valid.” coming from System stack System.ArgumentException HResult = 0x80070057 消息 = 参数无效。 来源 = System.Drawing。 为什么? - System.ArgumentException HResult = 0x80070057 Message = Parameter is not valid. Source = System.Drawing. Why? 给出“System.ArgumentException:&#39;参数无效。&#39; &quot; 当我从数据库中检索图像时 - Gives "System.ArgumentException: 'Parameter is not valid.' " when i retrieving image from database System.ArgumentException:“参数无效。” 在 C# 中从 SQL Server 获取图像 - System.ArgumentException: 'Parameter is not valid.' in C# get image from SQL Server 更新 Access 数据库后检索图像时出现问题(System.ArgumentException:'参数无效。') - Problem retrieving the image after updating the Access database (System.ArgumentException: 'Parameter is not valid.') DrawToBitmap - System.ArgumentException:参数无效 - DrawToBitmap - System.ArgumentException: Parameter is not valid
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM