[英]System.ArgumentException: Parameter is not valid. GraphicsPath.AddString
因此,在调试时遇到了这个问题,但是我遇到了访问冲突,但是当我在没有调试器的情况下运行时,出现了一个错误,告诉我参数无效。 它带我到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 ( );
}
用这行:
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
,请勿丢弃它们)。 让我展示一个非常幼稚的实现(易于扩展以缓存Pen
和SolidBrush
):
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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.