winform控件上的双向数据绑定动态对象

时间:2013-11-26 20:02:14

标签: c# winforms data-binding inotifypropertychanged expandoobject

我想将一个Dynamic对象数据绑定到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";
        }
    }

对于记录,如果我更改控件值,它会反映在动态属性上,这也是正常的。

为了完整起见,This post给了我这种方法。

1 个答案:

答案 0 :(得分:1)

简单地说,Binding无法响应您的DataSource的属性更改,因为它不知道它需要侦听的属性的名称,因为Binding的构造函数中没有提供属性名称(第3个参数) - 按设计。

为了克服这个问题,基本上,我们需要监听DataSource的更改并通知或强制Binding再次读取值。幸运的是,Binding类有一个公共方法ReadValue,它强制Binding再次从DataSource中读取值。

如果您使用以下行扩展代码,例如在将绑定添加到DataBindings集合之前,可以解决双向绑定。

((INotifyPropertyChanged)this.ViewData).PropertyChanged += (sender2, e2) =>
    {
        if (e2.PropertyName == "Test")
        {
            bind.ReadValue();
        }
    };

最后,所有这些变通方法都可以封装到一个很好的帮助方法中,以隐藏细节并尽可能地重复使用。