系统.参数无效.GraphicsPath.AddString

本文关键字:AddString GraphicsPath 无效 参数 系统 | 更新日期: 2023-09-27 18:13:10

所以我在调试时一直有这个问题,我得到一个访问冲突,但是当我在没有调试器的情况下运行时,我得到一个错误,告诉我参数无效。它引导我到path。addstring(…);有什么原因吗?老实说,所有参数都是正确的,否则编译器会捕获它。这让我很生气

        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 ( );
        }

系统.参数无效.GraphicsPath.AddString

加上这一行:

fontFamily.Dispose();

你正在处理this.Font.FontFamily对象。Control将处于无效状态,下一次对Paint的调用将失败。您还处理了Graphics对象,不要这样做,因为它可能在您的函数之后使用。

一般来说,你必须只处理你创建的对象,不多也不少(创建者有责任处理这些对象)。编译器无法捕获这类错误(除非运行静态代码分析),因为这是由程序执行路径引起的运行时错误。如果你很幸运,你会有一个异常(ArgumentException,因为你传递了一个无效的参数:一个处置字体)。

此外,您不需要显式调用Dispose(),使用using语句更安全(它也可以在异常情况下工作)。让我重构一下你的代码:

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);
    }
}

请注意,为每个油漆创建资源效率不高(允许但非常慢)。您应该尽可能地重用它们(例如使用字典)。此外,对于恒定的颜色,最好使用预定义的笔刷(例如Brushes.White,不要处理它们)。让我展示一个非常简单的实现(很容易扩展到同时缓存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];
}

那么它将像这样使用:

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