2

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

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

Для полноты, This post дал мне такой подход.

ответ

1

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

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

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

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

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