![](/img/trans.png)
[英]How can I get the type of thrown exception from CompletedEventArgs?
[英]How can I get rid of “Out of memory” exception thrown from Visual Studio designer?
請考慮以下代碼:
主表單模板模型:
public partial class CustomForm : Form
{
public CustomForm()
{
InitializeComponent();
DoubleBuffered = true;
}
}
具體表格模板型號:
public partial class PopupForm : CustomForm
{
public PopupForm()
{
InitializeComponent();
BTN_Maximize.Hide();
}
}
派生形式:
public partial class SiteAccess : CustomForm
{
public SiteAccess()
{
InitializeComponent();
this.SizeGripStyle = SizeGripStyle.Show;
}
}
(主要形式)
+
public partial class Edition : PopupForm
{
public Edition()
{
InitializeComponent();
}
}
+
public partial class Preferences : PopupForm
{
public Preferences()
{
InitializeComponent();
}
}
+
public partial class About : PopupForm
{
public About()
{
InitializeComponent();
}
}
在我的表單模板模型PopupForm中,我為一個空面板定義了一個Paint事件處理程序,如下所示:
private void PNL_TitleBar_Paint(object sender, PaintEventArgs e)
{
Brush gradientBrush = new LinearGradientBrush(new Point(0, 0),
new Point((int)e.ClipRectangle.Right, 0),
Color.Gray,
Color.FromArgb(255, 50, 50, 50));
Pen gradientPen = new Pen(gradientBrush);
e.Graphics.DrawLine(gradientPen,
new Point((int)e.ClipRectangle.Left, (int)e.ClipRectangle.Bottom - 1),
new Point((int)e.ClipRectangle.Right, (int)e.ClipRectangle.Bottom - 1));
gradientPen.Dispose();
gradientBrush.Dispose();
}
要簡化它,只需在面板底部繪制一條漸變線。
問題來自於每當我嘗試從PopupForm (版本,首選項或關於)的派生形式之一插入工具箱中的新控件時,我收到以下消息:
我之前向你展示了Paint事件處理程序的原因是因為我發現它是問題的根源,但我仍然不知道如何修復它。 實際上,如果我刪除了Paint事件處理程序的代碼,則根本不會拋出任何異常。
順便說一下,我必須指定一些東西:
但是,如果我重新構建解決方案(不執行程序)並返回到Designer,則在窗體中插入控件時將顯示異常。
有關這種奇怪行為的任何想法?
這是由代碼中的錯誤引起的。 底層異常是LinearGradientBrush構造函數拋出的GDI +異常。 由於難以解釋而臭名昭着,當它在設計時發生時會變得更糟。 從技術上講,這在運行時也可能出錯,只是不太可能。 您可以通過對代碼進行少量更改來一致地重新調整它:
Brush gradientBrush = new LinearGradientBrush(new Point(0, 0),
new Point((int)0, 0), // <=== here
Color.Gray,
Color.FromArgb(255, 50, 50, 50));
KABOOM。 使用e.ClipRectangle來初始化畫筆永遠是正確的,你得到的漸變是高度不可預測的。 e.ClipRectangle值的變化取決於窗口的哪個部分需要重新繪制,現在你完全依賴它作為整個窗口。 例如,當您將窗口拖離屏幕邊緣時,情況並非如此。 視覺神器應該非常明顯。
固定:
Brush gradientBrush = new LinearGradientBrush(new Point(0, 0),
new Point(this.ClientSize.Width, 0),
Color.Gray,
Color.FromArgb(255, 50, 50, 50));
必須修復DrawLine()調用以使線條出現在一致的位置。 不要擔心剪輯,Windows已經自動處理它。
外賣是要非常小心使用e.ClipRectangle屬性,它經常偶然工作,但幾乎不是你真正想要使用的。 只能用它來檢查是否可以跳過繪圖部件,因為它們位於裁剪區域之外。 哪些代碼很難獲得回報,在啟用Aero的現代Windows版本中不會經常發生。 不要打擾。
在Paint
處理程序中,您可以檢查DesignMode
屬性並在Forms Designer中跳過繪制標題欄:
void PNL_TitleBar_Paint(object sender, PaintEventArgs e)
{
if (DesignMode)
return;
using (Brush gradientBrush = new LinearGradientBrush(new Point(0, 0),
new Point((int)e.ClipRectangle.Right, 0),
Color.Gray,
Color.FromArgb(255, 50, 50, 50)))
using (Pen gradientPen = new Pen(gradientBrush))
{
e.Graphics.DrawLine(gradientPen,
new Point((int)e.ClipRectangle.Left, (int)e.ClipRectangle.Bottom - 1),
new Point((int)e.ClipRectangle.Right, (int)e.ClipRectangle.Bottom - 1));
}
}
這將適用於您的Paint
方法和大多數其他情況。 有關異常情況的討論,例如在構造函數中要做什么,請參閱此處 。
(建議還using
語句替換對Dispose
顯式調用。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.