2011-08-16 89 views
3

包含UserControl的WinForms表單在我嘗試在設計模式下顯示時引發異常,但在程序運行或調試時運行正常。WinForms設計器異常

設計師說:

變量 'fpInfoA' 要麼是未聲明或從未分配。
ResearchTool fMain.Designer.cs線:282柱:1 調用堆棧
在System.ComponentModel.Design.Serialization.CodeDomSerializerBase.Error(IDesignerSerializationManager經理,字符串exceptionText,字符串HELPLINK) 在System.ComponentModel.Design。 Serialization.CodeDomSerializerBase.DeserializeExpression(IDesignerSerializationManager經理,字符串名稱,CodeExpression表達) 在System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeExpression(IDesignerSerializationManager經理,字符串名稱,CodeExpression表達) 在System.ComponentModel.Design.Serialization.CodeDomSerializerBase。 DeserializeStatement(IDesignerSerializationManager管理器,CodeStatement語句)

但是,它看起來像變量賦值爲我希望在如何追查這個問題InitializeComponent

private void InitializeComponent() 
{ 
    // ... (Order of statements is same as in actual code) ... 
    this.tpFpA = new System.Windows.Forms.TabPage(); 
    this.fpInfoA = new ResearchTool.FPInfo(); 
    // ... 
    this.tpFpA.Controls.Add(this.fpInfoA); // THIS LINE BLOWS UP IN DESIGN MODE 
} 

的思考?例如,有沒有一種調試設計器初始化的方法?

回答

1

你會發現在如何跟蹤設計時代碼執行的信息:

What information do you need to fix a problem, which occurs with your products at design time?

+0

該鏈接似乎處理VS的崩潰實例的調試。在我的情況下,VS不會崩潰,它只是顯示一條錯誤消息而不是設計視圖。 –

+0

如果您按照此鏈接中的說明進行操作,您將會發現異常。我認爲這是你需要的。您將能夠設置斷點並調試您的代碼。試試這個,我多次使用這種技術,它的工作原理。 – platon

+0

是的,它做到了。用戶控件的初始化代碼在設計模式下拋出Exception,並且該異常未被VS報告。 –

5

之一的情況下,解決方法無法修復問題,將是圍繞問題的代碼位與檢查DesignMode

如:

private void InitializeComponent() 
{ 
    ... 
    if(!DesignMode) 
    { 
     this.fpInfoA = new ResearchTool.FPInfo(); 
    } 
    ... 
} 

這也可以加快它一點點,如果是這樣做,不需要在設計模式,並且是很慢的東西,如連接到數據庫或類似。

+0

麻煩不在InitializeComponent中,它是設計器後來的事情,this.fpInfoA未初始化。我會在這個問題上更新這個問題。 –

+0

@Eric您可以在'Form'中的任何位置使用'if(!DesignMode)',這樣您就可以圍繞在設計器中查看「Form」時調用的任何代碼。假設你在設計者當然不需要這些代碼。所以我不認爲你的評論會影響我的答案,除非我誤解。 –

+0

我不想從設計時間中刪除任何代碼。據我所見,所有代碼應該在設計器中運行。問題似乎是fpInfoA在設計模式下「神奇地」未分配,即使'InitializeComponents'中有清楚的分配。 –

0

As Hans Olsson said,這可能可以通過檢查設計模式和禁用違規邏輯來解決。

如果您的UserControl的構造函數有任何問題,也會觸發此錯誤。如果在設計師實例化UserControl時發生異常,設計師將會失敗。在我的情況下,失敗導致相同的「[...]要麼未申報,要麼從未分配過」「錯誤。

例如,請參見下面的用戶控件:

public class MyUserControl : UserControl { 

    public MyUserControl() 
    { 
     InitializeComponent(); 

     throw new Exception(); //Causes a designer error. 
    } 
} 

現在,觀察包含該MyUserControl的形式把設計師的時候,我們會看到類似以下內容:

Winforms Designer Error

我不能說如果設計者對於以前版本的Visual Studio是這樣的話;但對於Visual Sutdio 2017,您可以清楚地看到發生了什麼。

設計師失敗,因爲引發了System.Exception。結果,變量[REDACTED]被認爲是未聲明的或從未分配的,實際上自動生成的設計器代碼是正確的。問題出在MyUserControl的構造函數上。

現在,如果您需要將依賴於外部服務/資源的邏輯放在控件的構造函數中,則需要指出它只應在運行時發生。或者,您可以爲設計時提供模擬資源。

要做到這一點,你可以use the LicenseManager and check its current UsageMode。 下面的修改後的代碼現在只會在運行時引發異常,並且設計者不再有錯誤。

public class MyUserControl : UserControl { 

    public MyUserControl() 
    { 
     InitializeComponent(); 

     if (LicenseManager.UsageMode != LicenseUsageMode.Designtime) 
     { 
      throw new Exception(); //No longer fails in design-time. 
     } 
    } 
}