Let's look at a simple example: I want to create a Button class with a different
BackColor
and
Size
than the "normal" button (.Net 4, Windows Forms). Looks easy, doesnt't it? But I face some problems. A simple "solution" would be:
public class BernieButton : Button
..
public BernieButton()
{
this.BackColor = Color.Green;
this.Size = new Size(150,50);
}
Compile the project, drag a
BernieButton
onto
Form1
, and everything looks fine.
But now Sales decides that the
BackColor
must be yellow, and the size is too big. OK, change that in the constructor, test the new button, looks fine. Rebuild the old projects, and - the buttons there look like before. Failure!
How could that fail? When the button was dragged onto the form, the Designer added some lines in the
InitializeComponent
method of the form:
this.BernieButton1.BackColor = Color.Green;
this.BernieButton1.Size = new Size(150,50);
and that code gets executed after the constructor of the button, thus overriding the recent changes of the default value.
I tried overriding the properties:
[DefaultValue(typeof(Color), "Green")]
public override Color BackColor
{
get { return base.BackColor; }
set { base.BackColor = value; }
}
and then set the default value in the constructor (using reflection, thus circumventing double storage of the new default value). That really works as it is intended, the designer does not write a line for
BackColor
in the
InitializeComponent
method.
But it does not work with
Size
. There is an important difference:
BackColor
is "
virtual
" in the
Button
class,
Size
is not. I tried with the "
new
" keyword, but it fails: a line is added to
InitializeComponent
, and later changes of the default value are ignored.
I thought of setting the
DefaultValueAttribute
of the properties in the constructor. But that is not possible, attributes are read-only at run-time.
Do you have some ideas on how to overcome these limitations with inherited non-virtual properties?