开发者

VisualStudio 2010 Designer throws on implemented virtual method

开发者 https://www.devze.com 2023-03-12 08:04 出处:网络
I want to have an abstract UserControl, BaseControl, that implements an interface IBaseControl. However, setting the class to abstract breaks VisualStudio designer (This is a known issue with Visual S

I want to have an abstract UserControl, BaseControl, that implements an interface IBaseControl. However, setting the class to abstract breaks VisualStudio designer (This is a known issue with Visual Studio (e.g., see this StackOverflow posting for more info), and as far as I know, there's no change expected in the near future

So, to work around this, I make BaseControl not abstract, and its implementation of IBaseControl methods virtual. However, since these methods make no sense for a BaseControl (e.g., not all components have been added yet), I make them throw:

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开发者_Python百科 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.

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.

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! It only compiles and instantiates the base class of the control you are designing.

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. 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; 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. 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
  • 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消