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 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.
When the method is declared as virtual in a base class, and the same definition exists in a derived class, there is no need for override, but a different definition will only work if the method is overridden in the derived class. Two important rules: By default, methods are non-virtual, and they cannot be overridden.
By default, methods are non-virtual. You cannot override a non-virtual method. Virtual properties behave like virtual methods, except for the differences in declaration and invocation syntax. It is an error to use the virtual modifier on a static property.
The solution with empty virtual methods gives no information on what is supported by a specific document instance. Furthermore, it forces you to add all possible methods in the base class. This forces all clients to be updated as whel, when you decide that the base class needs additional methods.
Yes, abstract methods are virtual by definition; they must be overridable in order to actually be overridden by subclasses: When an instance method declaration includes an abstract modifier, that method is said to be an abstract method.
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With