2011-06-09 61 views
6

我想要一個摘要UserControl,BaseControl,它實現了一個接口IBaseControl。 然而,設置類抽象休息VisualStudio的設計(這是與Visual Studio(例如,參見this StackOverflow posting獲取更多信息),而據我所知,有no change expected in the near futureVisualStudio 2010 Designer引發實現的虛擬方法

於是,一個已知的問題來解決這個問題,我讓BaseControl不是抽象的,其實現的IBaseControl方法虛擬然而,由於這些方法並沒有什麼意義了BaseControl(例如,不是所有組件都已經被添加),我讓他們扔:

public class BaseControl : UserControl, IBaseControl 
{ 
    /// <summary> 
    /// This IBaseControl method is not abstract because 
    /// that breaks the Designer 
    /// </summary> 
    public virtual void LoadSettings() 
    { 
     throw new NotImplementedException("Implement in derived class."); 
    } 

    private void BaseControl_Load(object sender, EventArgs e) 
    { 
     // intention: derived methods automagically load their settings 
     this.LoadSettings(); 
    } 
} 

在導出的控件,我有相應的覆蓋:

public partial class DerivedControl : BaseControl 
{ 
    public override void LoadSettings() 
    { 
     // load settings 
    } 
} 

儘管如此,當我嘗試在設計器中打開控件時,出現一個錯誤,指示BaseControl.LoadSettings引發了異常。

現在,請記住LoadSettings是在基類中調用的,所以當Designer加載DerivedControl時,它依次調用BaseControl的加載方法,該方法會拋出。

您是否遇到過類似問題?你怎麼處理這件事?如果可能的話,我想有一個優雅的解決方案。

+0

沒有repro,我沒有想到一個。現在工具欄上有兩個控件,不要選錯了。你應該重寫OnLoad而不是使用Load事件。 – 2011-06-09 20:53:54

回答

6

引發異常的原因是,奇怪的是,設計師並沒有編譯或實例化您正在設計的類!它只編譯和實例化正在設計的控件的基類。

爲什麼這種情況變得很明顯,當你意識到爲元素添加新的子控件需要進一步的重新編譯。此外,您添加的每個事件處理程序都會修改該類,並再次需要重新編譯。由於事件處理程序永遠不會在設計器中調用,所以這完全沒有必要。你設計一個類類似你的班,但不是你的班;這是一項正在進行中的工作。

因爲只有基類被實例化,所以基類不能抽象,它需要功能,就像一樣。如果你拋出異常,那麼設計者就會看到它們。唯一可行的解​​決方案是:

  • 不從基類拋出異常,或
  • 有條件地不扔基於它是否是設計時還是不例外。

要麼會工作;使用你喜歡的或最適合你的設計的。這只是設計師的工作方式,因爲你提到它不太可能改變。

+1

太棒了,就是這樣!我現在使用'if(!DesignMode)'有條件地拋出。 – 2011-06-09 20:57:13