提问者:小点点

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


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

为了记录,如果我改变控件值,它会反映在动态属性上,这也是可以的。

为了完整起见,这篇文章给了我这个方法。


共1个答案

匿名用户

简单地说,绑定无法响应数据源的属性更改,因为它不知道它需要侦听的属性的名称,因为绑定的构造函数(第三个参数)中没有提供属性名称--这是设计的。

为了克服这个问题,基本上,我们需要监听数据源的变化,并通知或强制绑定重新读取值。幸运的是,绑定类有一个公共方法ReadValue,它强制绑定再次从DataSource读取值。

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

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

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

相关问题