Problems with properties of derived controls

C

Christian Weinert

Hello,
I currently fight with a problem during the derivative of WinForm controls.

In Visual Studio I created a new User Control. This control is derived from
the DataGridView of the System.Windows.Forms namespace. I want to use this
control as a template for futher controls. Within this control i want to set
some property values to be pre-defined for further derived controls.

My base class looks like this:

public partial class BaseDataGrid : System.Windows.Forms.DataGridView
{
private bool _Enabled;

public BaseDataGrid() : base()
{
InitializeComponent();
this.Enabled = false;
}

[DefaultValue(false)]
public new bool Enabled
{
get
{
return this._Enabled;
}
set
{
this._Enabled = value;
}
}
}

For testing this control I created a WinForm and put it on the form. Looking
at the property window shows the Enabled-Property as set to "true". and not
as expected to "false". The entry "true" is bold, so the Designer recognized
that the default value for this property is "false".

Further, I derived a new User Control from my BaseDataGridView control, put
it on my form. As the BaseDataGridView the property window shows the
Enabled-Property as set to "true".

It seems that the Designer uses the Property-Value of the next-higher level
control in a control hierarchy as the default value for this property. But,
for pre-defining the property it uses the property default value of the
highest class in the object hierarchy.

My second approch was not to "override" the Enabled-Property. I only set the
Enabled-property derived from the DataGridView to "false".

My BaseDataGrid-class now looks like this:

public partial class BaseDataGrid : System.Windows.Forms.DataGridView
{
public BaseDataGrid() : base()
{
this.Enabled = false;
}
}

One again, putting this control on a WinForm is suprising me. Within the
property window the Enabled-property is set to false. Everything seems to be
fine. But when changing it to "true" there will be not code is written into
the InitializeComponent-method of the form. When starting the form the
control will be disabled. Debugging the InitializeComponent-method shows that
the control has its Enabled-property set to "false".

Part of the InitializeComponent-method when putting the control on the form:

this.baseDataGrid1.ColumnHeadersHeightSizeMode =
System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.baseDataGrid1.Enabled = false;
this.baseDataGrid1.Location = new System.Drawing.Point(358, 88);
this.baseDataGrid1.Name = "baseDataGrid1";
this.baseDataGrid1.Size = new System.Drawing.Size(240, 150);
this.baseDataGrid1.TabIndex = 0;

Part of the InitializeComponent-method after setting the property to true:

this.baseDataGrid1.ColumnHeadersHeightSizeMode =
System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.baseDataGrid1.Location = new System.Drawing.Point(358, 88);
this.baseDataGrid1.Name = "baseDataGrid1";
this.baseDataGrid1.Size = new System.Drawing.Size(240, 150);
this.baseDataGrid1.TabIndex = 0;



Hope, anyone of you has an idea how to solve this problem.

Thanks and best regrads
Chris
 
I

Ignacio Machin ( .NET/ C# MVP )

That is not the way of doing it.

First let see where your error is.
Check the consequences of redefining a member using "new" . You can
look it up in MSDN, I will only say that the designer is not using
your new method but the method previously defined. This is cause it's
treating your control as a class Control instance and at that level
your method is not defined.

solution, do not redefine properties.
Simply assign your desired values in the constructor
 
C

Christian Weinert

Hello Ignacio,
thanks for Your reply. I was enjoying the good weather this weekend, so
sorry for my late delay.

First of, thanks for the important information about the fact, that a
pre-definition of a control property doesn't be used by the designer.

Your solution, to assign the desired values within the constructor was the
point where my problems began. I have changed my example to make my problem a
litte bit more "visual".

Lets take a textbox and build a new textbox control to be the base for all
further textboxes. Lets definie that the default back color of the textbox
should be blue.

The source code of the text box:

public partial class BaseTextBox : TextBox
{
public BaseTextBox()
:base()
{
InitializeComponent();
this.BackColor = Color.Blue;
}
}

I put this control on a WinForm. The back color of the control is blue.
Within the property window, the back color property is set to blue.
Everythink seems to be fine. But the setting is bold, so when saving the
form, it will be written to the InitializeComponent method.

The InitializeComponent method of the form:

private void InitializeComponent()
{
this.baseTextBox1 = new ControlInheritance.BaseTextBox();
this.SuspendLayout();
//
// baseTextBox1
//
this.baseTextBox1.BackColor = System.Drawing.Color.Blue;
this.baseTextBox1.Location = new System.Drawing.Point(12, 25);
this.baseTextBox1.Name = "baseTextBox1";
this.baseTextBox1.Size = new System.Drawing.Size(100, 20);
this.baseTextBox1.TabIndex = 0;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(292,266);
this.Controls.Add(this.baseTextBox1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
this.PerformLayout();
}

When understanding the use polymorphism right, changes at a class will take
affect everywhere, where it has been used. So lets try it. Lets say, the
default back color of our textbox should be red. First I will change the base
class code as follows:

public partial class BaseTextBox : TextBox
{
public BaseTextBox()
:base()
{
InitializeComponent();
this.BackColor = Color.Red;
}
}

When I open the form I already put the "former" base textbox on it, the
changes will not take affect: The old base text box is still blue, a new one
will be red...

This all happens because of the designer didn't recognize that we have
changed the "default" back color. The designer notice that the back color has
been changed from its default (as far as I know: SystemColor.Window) to the
new value blue. So You have to replace every used base textbox with its new
version :-(

A side effect I notice: Take the base textbox and change the bakc color to
the default (SystemColor.Window). The designer will never accepts any color
as default value...

BUT: this code will work fine...

public partial class BaseTextBox : TextBox, ISupportInitialize
{
public BaseTextBox()
: base()
{
InitializeComponent();
this.BackColor = Color.Blue ;
}

[DefaultValue(typeof(Color), "Blue")]
public new Color BackColor
{
get
{
return base.BackColor;
}
set
{
base.BackColor = value;
}
}

public void BeginInit()
{
}

public void EndInit()
{
Color c = this.BackColor;
}
}

The textbox on the form is blue. Replace Blue with Red and rebuild Your
projekt. Now the textbox will be red... But this is quit a dirty way to do
this...


Perhaps, I have a big error within my thinking, but hope anyone can help me...

Thanks
Chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top