簡體   English   中英

如何在圖像按鈕中將背景圖像設置為“無”或其他一些默認值?

[英]How do I set the background image to None, or some other default value, in an image button?

我正在解決這個問題,並創建一個簡單的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
    }
}

當我嘗試將此控件添加到設計器時,我得到

控件ImageButton在設計器中引發了未處理的異常,並且已被禁用。

例外:值不能為null。 參數名稱:圖像

堆棧跟蹤:ImageButton.cs:line48中的ImageButton.OnPaint(PaintEventArgs e)

第48行是此行:

e.Graphics.DrawImage(BackgroundImage, 0, 0);

我意識到拋出此錯誤是因為BackgroundImage沒有設置為值,但是我不確定如何在代碼中這樣做。 在實際的應用程序中,此類永遠不會添加到設計器中,而是以編程方式添加。 如何解決此異常?

    this.BackgroundImage = base.BackgroundImage;

是的,可以肯定,保證例外。 您希望有人在構造函數運行之前設置了BackgroundImage屬性。 這是不可能的,構造函數必須在控件上的任何屬性設置之前運行。

接下來出現問題的是,Paint事件也會在設計器中引發。 在將控件放到窗體上后立即發生。 那是一個Kaboom,用戶和您的代碼都尚未為BackgroundImage屬性提供值。 因此,只需修復方法:

protected override void OnPaint(PaintEventArgs e)
{
    if (BackgroundImage != null) e.Graphics.DrawImage(BackgroundImage, 0, 0);
}

我不知道C#,但我對此的猜測是將一個透明的1x1px圖像存儲在某個位置,並在init上分配該圖像。 這樣,會有圖像,但是什么也看不到。

或者,您可以嘗試在第48行附近添加一些檢查,如下所示:

if(BackgroundImage!=null){
    e.Graphics.DrawImage(BackGroundImage,0,0);
}

也許添加如下內容:

else{ //No background image
    //Draw some dummy/placeholder
}

還有一種方法是將DrawImage調用封裝在try{}塊中,並捕獲結果表達式。 如果是的話,您應該可以安全地使用一個空的catch{}塊。

要刪除背景圖片,只需編寫:

this.BackgroundImage = null;

如果在沒有圖像集的情況下不繪制該怎么辦,還可以在函數的開頭調用base。

base.OnPaint(e);

您的實現中有很多冗余代碼:請嘗試使用此修訂版...

public class ImageButton : Button
    {
        public ImageButton()
        {
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.UserPaint, true);
        }

        protected override void OnPaint(PaintEventArgs pevent)
        {
            //base.OnPaint(pevent); <-- NO LONGER NEEDED (WE DO NOT WANT THE SYSTEM TO PAINT THE BUTTON);
            if (this.BackgroundImage != null)
            {
                pevent.Graphics.DrawImage(this.BackgroundImage, 0, 0);
            }
            else
            {
                //Just fill in black (for example)
                pevent.Graphics.FillRectangle(new SolidBrush(Color.Black), this.ClientRectangle);
            }
        }

        protected override void OnPaintBackground(PaintEventArgs pevent)
        {
            base.OnPaintBackground(pevent);
            pevent.Graphics.FillRectangle(new SolidBrush(this.BackColor), this.ClientRectangle);
        }

        public override Image BackgroundImage
        {
            get
            {
                return base.BackgroundImage;
            }
            set
            {
                base.BackgroundImage = value;
                this.Size = base.BackgroundImage.Size;
                this.Refresh();
            }
        }
    } 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM