【发布时间】:2014-02-06 08:48:53
【问题描述】:
实现这一目标的最佳方法是什么?
一些示例代码:
为文本框添加绑定,并添加事件监听器:
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)。这只是因为 parent 包含启用/禁用的 Save 按钮,以及一个包含多个用户控件的多个页面的选项卡控件。它最终会想要处理所有孩子的属性更改,因此似乎是构建事物的最佳方式(??)
这是要绑定的对象/属性(基于此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;
}
}
我知道Binding 对象上有一个名为formattingEnabled 的参数,但这看起来与日期/时间/货币格式有关。
我看不到任何从 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 对象传递,但它仍然不是特别好,因为我必须单独维护该列表...
有什么想法吗?
【问题讨论】:
-
HandlePropertyChange 看起来是在表单的类中定义的 - 您可以直接从那里访问文本框
-
谢谢,我刚刚意识到示例代码有点过于简化了。不过好喊。你怎么看?
标签: c# winforms textbox inotifypropertychanged backcolor