简体   繁体   English

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

[英]VisualStudio 2010 Designer throws on implemented virtual method

I want to have an abstract UserControl , BaseControl , that implements an interface IBaseControl .我想要一个抽象的UserControlBaseControl ,它实现了一个接口IBaseControl However, setting the class to abstract breaks VisualStudio designer (This is a known issue with Visual Studio (eg, see this StackOverflow posting for more info), and as far as I know, there's no change expected in the near future但是,将 class 设置为抽象会破坏 VisualStudio 设计器(这是 Visual Studio 的一个已知问题(例如,有关更多信息,请参阅此 StackOverflow 帖子),据我所知, 预计在不久的将来不会有任何变化

So, to work around this, I make BaseControl not abstract, and its implementation of IBaseControl methods virtual.因此,为了解决这个问题,我使BaseControl不是抽象的,并且它对IBaseControl方法的实现是虚拟的。 However, since these methods make no sense for a BaseControl (eg, not all components have been added yet), I make them throw:但是,由于这些方法对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();
    }
}

In the derived control, I have the corresponding override:在派生控件中,我有相应的覆盖:

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

Despite this, when I try to open the control in the designer, I get an error indicating that the BaseControl.LoadSettings has thrown an exception.尽管如此,当我尝试在设计器中打开控件时,我收到一条错误消息,表明BaseControl.LoadSettings引发了异常。

Now, remember LoadSettings is called in the base class, so when the Designer loads the DerivedControl , it in turn calls the load method for the BaseControl , which throws.现在,请记住LoadSettings是在基础 class 中调用的,因此当设计器加载DerivedControl时,它会依次调用BaseControl的加载方法,这会抛出。

Have you encountered a similar problem?你遇到过类似的问题吗? How have you dealt with this?你是怎么处理的? I'd like to have an elegant solution, if possible.如果可能的话,我想要一个优雅的解决方案。

The reason that the exception is thrown is because, oddly enough, the designer doesn't compile or instantiate the class your are designing at all .抛出异常的原因是,奇怪的是,设计者根本没有编译或实例化您正在设计的 class It only compiles and instantiates the base class of the control you are designing.它只编译和实例化您正在设计的控件的基础 class。

Why this is the case becomes obvious when you realize that adding new subcontrols to the element would require further recompilation.当您意识到向元素添加新的子控件需要进一步重新编译时,为什么会出现这种情况变得显而易见。 Also, every event handler that you add modifies the class and again would require recompilation.此外,您添加的每个事件处理程序都会修改 class 并且再次需要重新编译。 Since event handlers will never be called in the designer anyway, this is all completely unnecessary.由于无论如何都不会在设计器中调用事件处理程序,因此这完全没有必要。 You design with a class that resembles your class but isn't your class;您使用类似于您的 class 但不是您的 class 的 class 进行设计; it's a work in progress.这是一项正在进行的工作。

Since only the base class is instantiated, the base class cannot be abstract and it needs to be functional as is .由于仅实例化了基础 class,因此基础 class 不能是抽象的,它需要按原样运行。 If you throw exceptions, then the designer will see them.如果你抛出异常,那么设计者会看到它们。 The only practical solution is to either:唯一实用的解决方案是:

  • Not throw exceptions from the base class, or不从基础 class 抛出异常,或
  • Conditionally not throw exceptions based on whether it is design-time or not.根据是否是设计时有条件地不抛出异常。

Either will work;两者都行; use whichever you prefer or works best for your design.使用您喜欢的或最适合您的设计的。 This is just the way the designer works and as you mention it is not likely to change.这正是设计师的工作方式,正如您所提到的,它不太可能改变。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM