I am developing a set of custom controls for a specific application. I want to define properties which is universal over the set of controls for appearance purposes, for argument's sake let's make it CustomCtrl.AccentColor
I want to define that same property for my Windows form i.e. Form1.AccentColor
and when I change it, all the custom controls' AccentColor
should change, exactly like when I change the ForeColor
of my form, all labels' and buttons' etc ForeColor
changes with it.
Is it at all possible to do this or do I have to settle for the effort of looping through all custom controls and changing it one-by-one?
Short Answer
Since you can have a common base class for all your controls as you mentioned in comments, as an option you can create a base class and then add some properties with behavior like ambient properties (like Font
) to the base control class.
Detailed Answer
An ambient property is a property on a control that, if not set, is retrieved from the parent control.
In our implementation, we get the value from parent Form
using FindForm
method. So in the implementation, when getting the property value, we check if the value equals to default value and if the parent from has the same property, we return the property value of the parent form, otherwise we return the property value of the control itself.
After adding XXXX
property, in this scenario we also should implement ShouldSerializeXXXX
and ResetXXXX
methods to let the designer when serialize the property and how to reset value when you right click on property and choose reset.
MyBaseControl
using System.Drawing;
using System.Windows.Forms;
public class MyBaseControl : Control
{
public MyBaseControl()
{
accentColor = Color.Empty;
}
private Color accentColor;
public Color AccentColor
{
get
{
if (accentColor == Color.Empty && ParentFormHasAccentColor())
return GetParentFormAccentColor();
return accentColor;
}
set
{
if (accentColor != value)
accentColor = value;
}
}
private bool ParentFormHasAccentColor()
{
return this.FindForm() != null &&
this.FindForm().GetType().GetProperty("AccentColor") != null;
}
private Color GetParentFormAccentColor()
{
if (ParentFormHasAccentColor())
return (Color)this.FindForm().GetType()
.GetProperty("AccentColor").GetValue(this.FindForm());
else
return Color.Red;
}
private bool ShouldSerializeAccentColor()
{
return this.AccentColor != GetParentFormAccentColor();
}
private void ResetAccentColor()
{
this.AccentColor = GetParentFormAccentColor();
}
}
MyBaseForm
public class BaseForm : Form
{
[DefaultValue("Red")]
public Color AccentColor { get; set; }
public BaseForm()
{
this.AccentColor = Color.Red;
}
}
Form1
public partial class Form1 : BaseForm
{
public Form1()
{
InitializeComponent();
}
}
i think you can create inherited class from Control class and define your common properties on there then inheriting your custom controls from that class and use parent property to access container (like Form) and get property value from it