我希望有一个抽象UserControl
,BaseControl
,它实现了一个接口IBaseControl
。
但是,将类设置为抽象会破坏VisualStudio设计器(这是Visual Studio的已知问题(例如,请参阅this StackOverflow posting以获取更多信息),据我所知,有no change expected in the near future
因此,要解决这个问题,我要使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
的加载方法,该方法会抛出。{/ p>
你遇到过类似的问题吗?你是怎么处理的?如果可能的话,我想要一个优雅的解决方案。
答案 0 :(得分:6)
抛出异常的原因是,奇怪的是,设计器不会编译或实例化你正在设计的类!它只编译和实例化你正在设计的控件的基类。
当您意识到向元素添加新的子控件时需要进一步重新编译时,为什么会出现这种情况。此外,您添加的每个事件处理程序都会修改该类,并且需要重新编译。因为无论如何都不会在设计器中调用事件处理程序,所以这完全没必要。你设计的课程类似你的班级,但不是你的班级;这是一项正在进行的工作。
由于只实例化了基类,因此基类不能是抽象的,而且需要功能,因为。如果你抛出异常,那么设计师就会看到它们。唯一可行的解决方案是:
要么工作;使用您喜欢的或最适合您的设计。这就是设计师的工作方式,正如你所提到的那样,它不太可能改变。