我想将一个动态对象数据绑定到winform应用程序中的控件。到目前为止,它有点工作了,它似乎“第一次”进行了数据绑定,但是当我更改属性值时,它对绑定的控件不起作用,这是我无法克服的问题。
下面是代码,如果您创建了一个带有文本框和按钮的新winform应用程序,您可以对其进行测试:
public partial class Form1 : Form
{
public dynamic ViewData { get; set; }
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.ViewData = new ExpandoObject();
this.ViewData.Test = "test1";
var bind = new Binding("Text", this.ViewData, null);
bind.Format += (o, c) => c.Value = this.ViewData.Test;
bind.Parse += (o, c) => this.ViewData.Test = c.Value;
textBox1.DataBindings.Add(bind);
this.ViewData.Test = "test2";
}
private void button1_Click(object sender, EventArgs e)
{
this.ViewData.Test = "test3";
}
}
为了记录,如果我改变控件值,它会反映在动态属性上,这也是可以的。
为了完整起见,这篇文章给了我这个方法。
简单地说,绑定无法响应数据源的属性更改,因为它不知道它需要侦听的属性的名称,因为绑定的构造函数(第三个参数)中没有提供属性名称--这是设计的。
为了克服这个问题,基本上,我们需要监听数据源的变化,并通知或强制绑定重新读取值。幸运的是,绑定类有一个公共方法ReadValue,它强制绑定再次从DataSource读取值。
如果使用以下行扩展代码(例如,在将绑定添加到DataBindings集合之前),则可以解决双向绑定问题。
((INotifyPropertyChanged)this.ViewData).PropertyChanged += (sender2, e2) =>
{
if (e2.PropertyName == "Test")
{
bind.ReadValue();
}
};
最后,所有这些变通方法都可以封装到一个很好的helper方法中,以隐藏细节并尽可能地使其可重用。