VisualStudio 2010 Designer会抛出已实现的虚拟方法

Gus*_*ori 6 c# user-controls abstract-class designer visual-studio

我想要一个抽象的UserControl,BaseControl实现一个接口IBaseControl.但是,将类设置为抽象会破坏VisualStudio设计器(这是Visual Studio的已知问题(例如,请参阅此StackOverflow发布以获取更多信息),据我所知,预计在不久的将来不会发生任何变化

所以,要解决这个问题,我BaseControl不是抽象的,而是IBaseControl虚拟方法的实现.但是,由于这些方法对于a没有意义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();
    }
}
Run Code Online (Sandbox Code Playgroud)

在派生控件中,我有相应的覆盖:

public partial class DerivedControl : BaseControl
{
    public override void LoadSettings()
    {
        // load settings
    }
}
Run Code Online (Sandbox Code Playgroud)

尽管如此,当我尝试在设计器中打开控件时,我收到一个错误,指示BaseControl.LoadSettings已抛出异常.

现在,记住LoadSettings在基类中调用,因此当Designer加载时DerivedControl,它依次调用BaseControl抛出的load方法.

你遇到过类似的问题吗?你是怎么处理的?如果可能的话,我想要一个优雅的解决方案.

Ric*_*key 6

抛出异常的原因是,奇怪的是,设计者根本不编译或实例化你正在设计的类!它只编译和实例化您正在设计的控件的基类.

当您意识到向元素添加新的子控件时需要进一步重新编译时,为什么会出现这种情况.此外,您添加的每个事件处理程序都会修改该类,并且需要重新编译.因为无论如何都不会在设计器中调用事件处理程序,所以这完全没必要.你设计的课程类似于你的班级,但不是你的班级; 这是一项正在进行的工作.

由于只实例化了基类,因此基类不能是抽象的,而是需要按原样运行.如果你抛出异常,那么设计师就会看到它们.唯一可行的解​​决方案是:

  • 不从基类中抛出异常,或
  • 有条件地不根据是否是设计时间抛出异常.

要么工作; 使用您喜欢的或最适合您的设计.这就是设计师的工作方式,正如您所提到的那样,它不太可能改变.