Reputation: 577
There is a Custom Property which depends on the value of other System Property to be initialized properly in WinForms.
Let me give you an example. Let's create a class WhateverButton: Button
with a Custom Property called MyExampleProperty
and system Control Property let's use this.Height
, which came from the Size of the Control.
public class WhateverButton : Button { // member private int m_myExampleProperty; // constructor public WhateverButton() { m_myExampleProperty = 1; } // Property public int MyExampleProperty { get => m_myExampleProperty; set { m_myExampleProperty= value > (this.Height / 2F) ? 1 : value; } } // Every time the Size change, update the property protected override void OnSizeChanged (EventArgs e) { base.OnSizeChanged (e); m_myExampleProperty = m_myExampleProperty > this.Height / 2F ? 1: m_myExampleProperty; } }
Add the WhateverButton
in the Form (with a size greater than default). WinForms generates the element (button, label, textbox and etc) by alphabetical order such as:
this.buttonWhatever.Location = new System.Drawing.Point (413, 57); // L this.buttonWhatever.Margin = new System.Windows.Forms.Padding (3, 4, 3, 4); // M this.buttonWhatever.MyExampleProperty= 30; // M ... // Others Properties this.buttonWhatever.Name = "myElement"; // N this.buttonWhatever.Size = new System.Drawing.Size (50, 80); // S this.buttonWhatever.Text = "My Element"; // T
After changing the Property MyExampleProperty
value by Form UI, it seems it works, but after saving the form (Ctrl+S) the property returns to 1.
Debugging
is possible to figure it out that every time the Form is saved all the elements are created again by that order. When the time of the MyExampleProperty
arrives the Size
property is not created yet, which will assume the default Height
and Width
and of course, the value of the property will be wrong. If I just rename the MyExampleProperty
to any other name that will be placed after the Size
property in this example, it will work. Maybe I am missing something that I have no idea to search.
Upvotes: 0
Views: 2011
Reputation: 273540
The problem with your property is that if the control is not the right height at the time of setting the property, the value passed to the setter is lost forever.
Therefore, in the setter, you should always assign value
to the backing field, and check the height in the getter:
public int MyExampleProperty
{
get => m_myExampleProperty > (this.Height / 2F) ? 1 : m_myExampleProperty;
set
{
m_myExampleProperty = value;
}
}
This way, you don't even need to handle the SizeChanged
event!
Or even better, write this as two properties:
public int MyExampleProperty { get; set; }
public int MyExamplePropertyThatChangesWithSize =>
MyExampleProperty > (this.Height / 2F) ? 1 : MyExampleProperty;
...because properties where you don't get the value that you just set is quite unexpected and can be confusing.
Upvotes: 1