如何在图像按钮中将背景图像设置为“无”或其他一些默认值?

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未将其设置为值,但是我不确定如何在代码中这样做。在实际的应用程序中,此类永远不会添加到设计器中,而是以编程方式添加。如何解决此异常?

Han*_*ant 5

    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)