If you want this, your class ButtonDesign
is not a Button, it has a Button and a Layout. Similarly your class TextBoxDesign
has a TextBox and a Layout.
In other words: don't use inheritance, use aggregation!
Every property that are both in Buttons
, TextBoxes
, and other Controls
that have the properties that you want to change for all items in one statement, create a class that contains all these properties, with the proper events.
For every property you need a private member, a public get/set property and an event that will be raised when the property changes. Something like this:
class Layout
{
private Color backColor; // TODO: give proper initial values
private Color foreColor;
... // other properties that you want to change for all Controls
// Events:
public event EventHander BackColorChanged;
public event EventHandler ForeColorChanged;
... // etc
// Event raisers:
protected virtual void OnBackColorChanged()
{
this.BackColorChanged?.Invoke(this, EventArgs.Empty);
}
protected virtual void OnForColorChanged()
{
this.ForeColorChanged?.Invoke(this, EventArgs.Empty);
}
...
// Properties:
public Color BackColor
{
get => this.backColor;
set => if (this.BackColor != value) this.OnBackColorChanged();
}
public Color ForeColor ...
public Size Size ...
}
Your DesignButton will be a UserControl
that has a Docked Button and a Layout. The constructor subscribes to the events. When raise the corresponding property on the button is set.
Use the visual studio designer to create the UserControl. Code will be similar to the following:
class MyButton : UserControl
{
private Button button; // visual studio designer will create this
private Layout layout;
public Layout Layout
{
get => this.layout;
set => if (this.Layout != value) this.ChangeLayout;
}
// you can't set the design properties. Only get.
protected Button Button => this.button;
Color BackColor
{
public get => this.Button.BackColor;
private set => this.Button.BackColor = value;
}
// etc for ForeColor, Text, ...
protected virtual void ChangeLayout(Layout newLayout)
{
// TODO: if there is an old Layout: desubscribe from all events from old Layout
this.layout = newLayout;
// subscribe to all events:
this.layout.BackColorChanged += this.BackColor_Changed;
this.layout.forColorChanged += this.ForColor_Changed;
...
this.BackColor = this.BackColor;
// TODO: if desired, for completeness add an event: LayoutChanged
}
Now whenever Layout raises event BackColorChanged you handle this event and assign the value to the Button. You'll get the gist.
Do something similar for TextBoxes, ComboBoxes, etc
Usage:
Layout commonLayout = new Layout
{
BackColor = Color.Yellow,
ForeColor = color.Black,
...
};
MyButton button1 = new MyButton
{
Layout = commonLayout,
};
MyTextBox textBox1 = new MyTextBox
{
Layout = commonLayout,
}
MyComboBox comboBox1 = ...
// Change the backgroundColor for all items:
commonLayout.BackColor = Color.Red;
If you have a lot of properties, consider to use generic classes
class LayoutProperty<T>
{
private T propertyValue;
public event eventHandler PropertyValueChanged
protected void OnPropertyValueChanged()
{
this.PropertyValueChanged?.Invoke(this, EventArgs.Empty);
}
public T PropertyValue
{
get => this.propertyValue;
set => if (this.PropertyValue != value) this.OnPropertyValueChanged();
}
}
class Layout
{
private PropertyValue<Color> backColor;
private PropertyValue<Color> foreColor;
// etc, see above for subscribtion and raising events.
And for all Controls:
public MyControl
{
private Control control;
private Layout layout;
// etc, see above for the event handling.
}
public MyButton : MyControl {Control = new Button()}
public MyTextBox : MyControl {Control = new Textbox()}