Я работаю над приложением Windows Forms, которое, конечно, включает привязку данных к объектам.
Из того, что я понял, двусторонняя привязка данных не работает "из коробки" с .NET.
Моя проблема в том, что я не могу найти непротиворечивую информацию о его реализации:
Согласно ".NET WinForms в двух словах", я должен создать событие для каждого свойства, которое называется Изменено, и запустить его в установщике связанного свойства.
Согласно онлайн-источникам (включая MSDN), мне просто нужно реализовать INotifyPropertyChanged в моем классе и запустить событие PropertyChanged во всех установщиках, передавая имя свойства.
Однако, предполагая, что у меня есть простой пользовательский интерфейс с привязкой данных текстового поля к свойству класса (реализующий любой из вышеуказанных методов), если я устанавливаю значение свойства базы данных в коде, пользовательский интерфейс не отражает изменения, используя любой из методов.
Так чего мне здесь не хватает?
Редактировать
Я должен был упомянуть, что INotifyPropertyChanged реализован не в объявлении соответствующих классов, а через динамическую генерацию кода, примерно эквивалентную DynamicProxy. Я создаю новый вопрос для этой темы, поскольку ответ соответствует актуальному вопросу.
Другое редактирование INotifyPropertyChanged правильно реализован инструментом генерации кода, я проверил эту точку, приведя экземпляр прокси-объекта к INotifyPropertyChanged, и зарегистрировал обработчик для события, которое вызывается при значение свойства изменено.
UpdateMode привязок данных установлен на NotifyPropertyChanged, а для CausesValidation установлено значение false для связанного элемента управления.
Итак, псевдокод выглядит так:
class MyForm {
MyClass localObj;
BindingSource mySource = new BindingSource();
MyForm(MyClass obj) {
localObj = obj.CreateProxy() // Ensures localObj is a proxy instance
mySource.Datasource = localObj // After this, UI is updated accordingly
localObj.someProperty = "I changed the value" // Here, the NotifyPropertyChanged event does get fired, but the UI does not update. Hence my question...
Console.WriteLine(localObj.someProperty) // Output is 'I changed the value'
}
}
Таким образом, единственный способ обновить пользовательский интерфейс - это вызвать ResetBindings для BindingSource ... что отрицательно сказывается на цели двухстороннего связывания IMHO.
Наконец-то !!
Проблема исходит от дизайнера. Во время разработки у меня нет доступа к реальному типу прокси бизнес-объекта, который является типом времени выполнения, сгенерированным прокси (который является функциональным, у меня нет сомнений в этой части). Таким образом, BindingSource инициализируется дизайнером с использованием известного типа данных бизнес-объекта, а не типа данных прокси (который является классом, унаследованным от класса BO)
Следовательно, источник данных должен быть инициализирован вручную с типом среды выполнения прокси-объекта для правильной двусторонней привязки.
Рабочая версия выглядит следующим образом (в псевдо-C #):
class MyForm {
Object localObj;
BindingSource mySource;
MyForm(MyClass obj) {
localObj = obj.CreateProxy() // Ensures localObj is a proxy instance
((ISupportInitialize) mySource).BeginInit()
mySource.Datasource = localObj.GetType()
((ISupportInitialize) mySource).EndInit()
mySource.Datasource = localObj // After this, UI is updated accordingly
localObj.someProperty = "I changed the value" // UI updates ! :)
}
}
Спасибо всем за советы и помощь, вы только что спасли мой день. Я бился головой об стену на этом!