Динамический объект двусторонней привязки данных в элементах управления 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";
        }
    }

Для записи, если я изменю значение элемента управления, это отразится на динамическом свойстве, что тоже нормально.

Для полноты картины Этот пост дал мне такой подход.


person Chuck Norris    schedule 26.11.2013    source источник


Ответы (1)


Просто Binding не может реагировать на изменения свойств вашего источника данных, поскольку ему не известно имя свойства, которое ему нужно прослушивать, потому что имя свойства не предоставляется в конструкторе Binding (3-й параметр) - по дизайну.

Чтобы решить эту проблему, в основном, нам нужно прослушивать изменения DataSource и сообщать или заставлять Binding снова прочитать значение. К счастью, в классе Binding есть открытый метод ReadValue, который заставляет Binding снова прочитать значение из DataSource.

Если вы расширите свой код следующей строкой, например перед добавлением привязки в коллекцию DataBindings, которая может решить двусторонние привязки.

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

В конце концов, все эти обходные пути могут быть инкапсулированы в хороший вспомогательный метод, чтобы скрыть детали и сделать его максимально пригодным для повторного использования.

person hollo    schedule 26.08.2014