Pass properties of parent control to children cont

2019-07-20 05:10发布

问题:

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?

回答1:

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();
    }
}


回答2:

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