Ric*_*ano 1 c# button winforms
我正在解决这个问题,并创建一个简单的ImageButton类,该类表示仅包含图像的按钮。我实现了(至少我相信我做到了)此答案中的建议,但该代码仍然出现异常:
public class ImageButton : Button
{
// Overrides the property
public override Image BackgroundImage
{
get { return base.BackgroundImage; }
set
{
base.BackgroundImage = value;
if (value != null) this.Size = value.Size;
}
}
// Shadows the property (note the -new- keyword)
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new Size Size
{
get
{
return base.Size;
}
set
{
base.Size = value;
}
}
public ImageButton()
{
this.BackgroundImage = base.BackgroundImage;
this.BackgroundImageChanged += new EventHandler(ImageButton_BackgroundImageChanged);
}
void ImageButton_BackgroundImageChanged(object sender, EventArgs e)
{
this.Size = this.BackgroundImage.Size;
}
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.DrawImage(BackgroundImage, 0, 0); // <-- Error occurs here
}
protected override void OnPaintBackground(PaintEventArgs e)
{
// Do nothing
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试将此控件添加到设计器时,我得到
控件ImageButton在设计器中引发了未处理的异常,并且已被禁用。
例外:值不能为null。参数名称:图像
堆栈跟踪:ImageButton.cs:line48中的ImageButton.OnPaint(PaintEventArgs e)
第48行是此行:
e.Graphics.DrawImage(BackgroundImage, 0, 0);
Run Code Online (Sandbox Code Playgroud)
我意识到抛出此错误是因为BackgroundImage未将其设置为值,但是我不确定如何在代码中这样做。在实际的应用程序中,此类永远不会添加到设计器中,而是以编程方式添加。如何解决此异常?
this.BackgroundImage = base.BackgroundImage;
Run Code Online (Sandbox Code Playgroud)
是的,可以肯定,保证例外。您希望有人在构造函数运行之前设置了BackgroundImage属性。这是不可能的,构造函数必须在控件上的任何属性设置之前运行。
接下来出现问题的是,Paint事件也会在设计器中引发。在将控件放到窗体上后立即发生。那是一个Kaboom,用户和您的代码都尚未为BackgroundImage属性提供值。因此,只需修复方法:
protected override void OnPaint(PaintEventArgs e)
{
if (BackgroundImage != null) e.Graphics.DrawImage(BackgroundImage, 0, 0);
}
Run Code Online (Sandbox Code Playgroud)