[英]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.