有没有一种简单的方法可以 link 两个对象 属性 在一起?

Is there an easy way to link two objects property together?

在 .NET 4.5 中使用 c# 和 winforms 我想 link 菜单项的 Checked 属性 和 Visible 属性一个表格。

更改这两个属性中的任何一个都会更改另一个属性以保持同步。

是否有一个简单而优雅的解决方案来做到这一点?

类似于这个带有复选框和按钮的示例:

连接到 CheckedChanged 事件

    private void checkBox1_CheckedChanged(object sender, EventArgs e)
    {
        var checkBox = sender as CheckBox;
        button1.Visible = !checkBox.Checked;
    }

编辑:

好吧,我误会了。

虽然 'farid' 的解决方案是一个干净的解决方案,使用视图模型和模型分离了关注点,但它也增加了您的应用程序的复杂性。

如果您不想使用此 mvvm 模式并将逻辑放在后面的代码中,您可以将 INotifyPropertyChanged 接口实现到具有可见 属性 的表单(或添加自定义事件),添加一个新的 Visible 属性 来设置 base.visible 属性(由 Form 从 Control class 继承)并引发 PropertyChanged 事件。在包含菜单项的表单中,您可以连接事件并执行必要的逻辑来设置选中状态或执行其他操作。

这是一个例子:

Form1后面的代码:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        this.Load += new System.EventHandler(this.Form1_Load);
    }

    private Form2 _frm2;

    private void Form1_Load(object sender, EventArgs e)
    {
        _frm2 = new Form2();
        _frm2.MdiParent = this;
        _frm2.PropertyChanged += _frm2_PropertyChanged;
        _frm2.Show();
    }

    void _frm2_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "Visible")
        {
            showToolStripMenuItem.Checked = _frm2.Visible;
        }
    }

    private void showToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
    {
        var menuItem = sender as ToolStripMenuItem;

        if (_frm2 != null)
            _frm2.Visible = menuItem.Checked;
    }
}

Form2后面的代码:

public partial class Form2 : Form, INotifyPropertyChanged
{
    public Form2()
    {
        InitializeComponent();
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public new bool Visible
    {
        get 
        {
            return base.Visible; 
        }
        set
        {
            base.Visible = value;
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs("Visible"));
        }
    }

    private void hideButton_Click(object sender, EventArgs e)
    {
        Visible = false;
    }
}

您可以使用 Windows Forms Data Bindings.

每个 windows 表单控件都有一个 DataBindings 属性,可用于将给定数据源中的 属性 绑定到控件属性之一。

您可以像下面的示例一样构建您的代码:

此示例显示了从 ViewModel 对象到控件 属性 的绑定。在您的特定情况下,您可以将 ViewModel 属性 绑定到两个控件 属性。

public partial class WhosebugForm : Form
{
        public ViewModel Model { get; set; }
        public Dictionary<string, Control> BindableControls { get; set; }
        public WhosebugForm()
        {
            Model = new ViewModel();
            Model.PropertyChanged += Model_PropertyChanged;
            BindableControls = new Dictionary<string, Control>();
            Model.Visible = false;
            InitializeComponent();
            RegisterBinding(boundButton, "Visible", Model, "Visible");
        }

        void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            foreach (var item in BindableControls)
            {
                NotifyChange(item.Value, e.PropertyName);
            }
        }

        private void NotifyChange(Control control, string propertyName)
        {
            button1.DataBindings[propertyName].ReadValue();
        }

        private void RegisterBinding(Control control, string controlPropertyName, ViewModel _model, string modelPropertyName)
        {
            control.DataBindings.Add(controlPropertyName, _model, modelPropertyName, true, DataSourceUpdateMode.OnPropertyChanged);
            BindableControls[control.Name] = control;
        }
        private void SetPropertyButton_Click(object sender, EventArgs e)
        {
            Model.Visible = true;
        }
    }

    public class ViewModel : INotifyPropertyChanged
    {
        private bool _IsVisible;
        public bool Visible
        {
            get
            {
                return _IsVisible;
            }
            set
            {
                _IsVisible = value;
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs("Visible"));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

我以用作控件的绑定数据源的形式定义了一个 ViewModel 对象。 (具有可见 属性)

private void RegisterBinding(Control control, string controlPropertyName, ViewModel _model, string modelPropertyName)
 {
     control.DataBindings.Add(controlPropertyName, _model, modelPropertyName, true, DataSourceUpdateMode.OnPropertyChanged);
            BindableControls[control.Name] = control;
 }

使用RegisterBinding方法注册简单绑定(参数够简单)

'ViewModel' class 在 System.ComponentModel 中实现了 INotifyPropertyChanged 接口。此接口添加一个 PropertyChanged 事件以在 ViewModel 中的任何 属性 更改时调用。

在窗体的构造函数中,我将事件监听器添加到监听器中 ViewModelPropertyChanged 事件,我强制绑定为绑定为其注册的每个控件读取新值。这部分代码刷新了绑定控件并改变了按钮的可见状态。

注意: 为了简单起见,我假设 ViewModel 中绑定到控件 属性 的属性与目标 [=49] 具有相同的名称=] 在表单控件中。 (Mode.Visible 和 boundButton.Visible)。如果你想为源属性和目标属性实现 属性 名称映射,你可以使用 Dictionary 或其他东西来实现此功能。