让我们假设您有一个绑定控件的属性对象。像这样:
MyClass MyObject = new MyClass();
MyObject.MyProperty = "Hello StackOverflow!";
MyTextBox.DataBindings.Add("Text", MyObject, nameOf(MyObject.MyProperty);
然后您将MyObject
更改为MyClass
的新实例,如下所示:
MyObject = new MyClass();
MyObject.MyProperty = "I've made a new instance of my class...";
然后MyTextBox
仍将绑定到MyClass
的实例,其中MyProperty
设置为" Hello StackOverflow!" 。反正有没有设置数据绑定,以便它坚持使用类的新实例?我知道我可以再次设置DataBindings,但有时候这并不像在这个例子中那么简单。
答案 0 :(得分:0)
数据绑定支持source属性的属性路径。因此,只要将MyObject
变量放在另一个可用于数据绑定的对象中并将其作为属性公开,就可以指定引用该属性的属性名称,然后是一个点,然后是你真正想要的财产。
例如,我们假设您有一个Model
类,其属性值为MyClass
:
class Model : INotifyPropertyChanged
{
private MyClass _myClass;
public MyClass MyClass
{
get { return _myClass; }
set { _UpdateField(ref _myClass, value); }
}
}
(上面假设一个辅助方法_UpdateField()
处理更新字段并根据需要提升PropertyChanged
事件。)
然后你可以这样定义你的绑定:
Model model = new Model(); // initialized somewhere you can access this reference later
model.MyClass.MyProperty = "Hello StackOverflow!";
MyTextBox.DataBindings.Add("Text", model,
nameof(Model.MyClass) + "." + nameof(MyClass.MyProperty);
然后,当您想要更新MyClass
对象时,可以更改model.MyClass
属性值。绑定将相应地更新目标值。
这是一个完整的示例(* .Designer.cs文件除外...只需确保表单上有Label
和Button
,并使用其默认名称并将Button.Click
事件订阅到处理程序在下面的代码中):
public partial class Form1 : Form
{
private readonly C2[] _rgc2 =
{
new C2 { Text = "First C2" },
new C2 { Text = "Second C2" },
};
private readonly C1 _c1 = new C1();
private bool _toggle = false;
public Form1()
{
InitializeComponent();
label1.DataBindings.Add("Text", _c1, nameof(C1.C2) + "." + nameof(C2.Text));
_UpdateC2();
}
private void _UpdateC2()
{
_c1.C2 = _rgc2[_toggle ? 1 : 0];
}
private void button1_Click(object sender, EventArgs e)
{
_toggle = !_toggle;
_UpdateC2();
}
}
class C1 : NotifyPropertyChangedBase
{
private C2 _c2;
public C2 C2
{
get { return _c2; }
set { _UpdateField(ref _c2, value); }
}
}
class C2 : NotifyPropertyChangedBase
{
private string _text;
public string Text
{
get { return _text; }
set { _UpdateField(ref _text, value); }
}
}
class NotifyPropertyChangedBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void _UpdateField<T>(ref T field, T newValue,
Action<T> onChangedCallback = null,
[CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, newValue))
{
return;
}
T oldValue = field;
field = newValue;
onChangedCallback?.Invoke(oldValue);
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}