当绑定属性发生变化时,更改文本框的背景颜色?

时间:2014-02-06 08:48:53

标签: c# winforms textbox inotifypropertychanged backcolor

实现这一目标的最佳方法是什么?

一些示例代码:

将绑定添加到文本框,并添加事件侦听器:

this.MyObject = new MyObject();

this.myTextBox.DataBindings.Add(
    new Binding("Text", this.MyObject, "MyProperty", true,
        DataSourceUpdateMode.OnPropertyChanged));

this.myOtherTextBox.DataBindings.Add(
    new Binding("Text", this.MyObject, "MyOtherProperty", true,
        DataSourceUpdateMode.OnPropertyChanged));

this.MyObject.PropertyChanged += handler;

PropertyChangedEventHandler handler从父用户控件传入new PropertyChangedEventHandler(HandlePropertyChange)。这只是因为父包含启用/禁用的“保存”按钮,以及包含多个用户控件的多个页面的选项卡控件。它最终会想要处理所有孩子的属性变化,所以似乎是构建事物的最佳方式(??)

这是要绑定的对象/属性(基于此https://stackoverflow.com/a/1316566/1061602

public class MyObject : INotifyPropertyChanged
{
    private int myProperty;
    public int MyProperty
    {
      get { return myProperty; }
      set { SetField(ref myProperty, value, () => MyProperty); }
    }

    private int myOtherProperty;
    public int MyOtherProperty
    {
      get { return myOtherProperty; }
      set { SetField(ref myOtherProperty, value, () => MyOtherProperty); }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged<T>(Expression<Func<T>> selectorExpression)
    {
      if (selectorExpression == null) throw new ArgumentNullException("selectorExpression");
      var body = selectorExpression.Body as MemberExpression;
      if (body == null) throw new ArgumentException("The body must be a member expression");
      OnPropertyChanged(body.Member.Name);
    }

    protected virtual void OnPropertyChanged(string propertyName)
    {
      PropertyChangedEventHandler handler = PropertyChanged;
      if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    protected bool SetField<T>(ref T field, T value, Expression<Func<T>> selectorExpression)
    {
      if (EqualityComparer<T>.Default.Equals(field, value)) return false;

      field = value;
      OnPropertyChanged(selectorExpression);
      return true;
    }
}

我知道formattingEnabled对象上有一个名为Binding的参数,但这看起来与日期/时间/货币格式有关。

我看不到从PropertyChangedEvent回到文本框的任何方法,因为它只是引用了属性本身。

我看到了这个:Binding a bool property to BackColor Property of a WinForm - 但我不确定添加额外的属性是否是最好的方法?

更新

根据邦德的回答,我可以这样做:

this.MyObject.PropertyChanged += (s, e) => handler(this.Controls, e);

因此将用户控件上的整个ControlCollection传递给事件处理程序。

然后让事件处理程序执行此操作:

public void ConfigChanged(object sender, EventArgs e)
{
  if (sender is ControlCollection)
  {
    var allControls = (ControlCollection)sender;
    foreach (var control in allControls)
    {
      if (control is TextBox)
      {
        var textBox = (TextBox)control;
        if (textBox.DataBindings[0].BindingMemberInfo.BindingField == 
            (e as PropertyChangedEventArgs).PropertyName)
        {
          textBox.BackColor = Color.LightGoldenrodYellow;
        }
      }
    }
  }
  this.saveButton.Enabled = true;
}

但它似乎不实用,如果表单发生了变化(例如将一些文本框放入组合框中,或者想要对其他控件类型执行相同操作),它将不再有效。

我想在用户控制方面,我会知道我想绑定哪些控件,所以我可以创建一个这些控件的集合并将它们作为sender对象传递,但它仍然不是特别的很好,因为我必须单独维护该列表...

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

你可以这样做

this.MyObject.PropertyChanged += (s, e) => handler(myTextBox, e);