将父控件的属性传递给子控件 [英] Pass properties of parent control to children controls

查看:55
本文介绍了将父控件的属性传递给子控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为特定应用程序开发一组自定义控件.我想为外观目的定义在一组控件上通用的属性,为了论证,让我们将其设为 CustomCtrl.AccentColor

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

我想为我的 Windows 窗体定义相同的属性,即 Form1.AccentColor,当我改变它时,所有自定义控件的 AccentColor 都应该改变,就像什么时候一样我更改表单的 ForeColor,所有标签和按钮等 ForeColor 随之更改.

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?

推荐答案

简短回答

由于您可以为您在评论中提到的所有控件创建一个公共基类,因此您可以选择创建一个基类,然后添加一些具有诸如 ambient 属性(如 Font)基础控件类.

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.

详细解答

环境属性是控件上的属性,如果未设置,则从父控件中检索.

An ambient property is a property on a control that, if not set, is retrieved from the parent control.

在我们的实现中,我们使用 FindForm 方法从父 Form 获取值.所以在实现中,在获取属性值时,我们检查该值是否等于默认值,如果父表单的属性相同,则返回父窗体的属性值,否则返回控件本身的属性值.

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.

添加XXXX属性后,在这个场景中我们还应该实现ShouldSerializeXXXXResetXXXX方法,让设计者在序列化属性时以及如何右键单击属性并选择重置时重置值.

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

这篇关于将父控件的属性传递给子控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆