Сведения о вопросе

rjevskii

07:22, 14th August, 2020

Теги

c#   .net   winforms    

WinForms привязка данных и внешние ключевые связи

Просмотров: 475   Ответов: 5

Я разрабатываю приложение WinForms (.Net 3.5, no WPF), где я хочу иметь возможность отображать внешние ключи поиска в базе данных DataGridView.

Примером такого рода отношений является то, что у меня есть таблица OrderLines. Линии заказов имеют отношение внешнего ключа к продуктам, а продукты, в свою очередь, имеют отношение внешнего ключа к ProductTypes.

Я бы хотел иметь базу данных DataGridView, где каждая строка представляет собой строку заказа, отображающую продукт и тип продукта этой строки.

Пользователи могут добавлять или редактировать строки заказов непосредственно в сетку и выбирать продукт для строки заказа из comboBoxColumn - это должно затем обновить столбец producttype, отображающий тип продукта для выбранного продукта, в той же строке.

Самый близкий к хорошему подходу, который я нашел до сих пор, - это ввести объект домена, представляющий линию порядка, а затем привязать DataGridView к коллекции этих линий порядка. Затем я добавляю свойства к объекту orderline, которые предоставляют продукт и producttype, и вызываю соответствующие события notifypropertychanged, чтобы поддерживать все в актуальном состоянии. В моем репозитории orderline я могу затем связать сопоставления между этим объектом orderline и тремя таблицами в моей базе данных.

Это работает на стороне привязки данных, но необходимость передавать код всего этого OR-mapping в репозитории кажется плохой. Я думал, что nHibernate сможет помочь с этим подключением, но я борюсь с сопоставлениями через все внешние ключи - они, кажется, работают нормально (поиск foreignkey для продукта orderline создает правильный объект product на основе внешнего ключа), пока я не попытаюсь выполнить привязку данных, я не могу получить столбцы идентификаторов databound для обновления моего продукта или объектов producttype.

Является ли мой общий подход даже в правильном направлении? Если это так, то каково хорошее решение проблемы картографирования?

Или есть ли лучшее решение для привязки данных строк, включая поиск внешних ключей, которое я даже не рассматривал?



  Сведения об ответе

repe

15:35, 5th August, 2020

Я думаю, что проблема, с которой вы столкнулись, заключается в том, что при привязке к сетке недостаточно поддерживать INotifyPropertyChanged, но вы должны запустить события ListChanged в вашей реализации IBindingList и убедиться, что вы переопределяете и возвращаете true для свойства SupportsChangeNotification . Если вы не вернете true для этого, сетка не будет искать его, чтобы узнать, изменились ли данные.

В .NET 2.0+ вы можете создать универсальную коллекцию, используя класс BindingList, это позаботится о большей части неприятностей (только не забудьте переопределить и вернуть true для свойства SupportsChangeNotification).

Если класс, используемый для привязки данных, имеет свойство, которое является коллекцией (например, IBindingList или BindingList), то вы можете привязать сетку внешнего ключа непосредственно к этому свойству. При настройке Привязок в конструкторе форм просто выберите свойство коллекции в качестве источника данных для таблицы. Это должно быть "just work". Единственная хитрая часть-это убедиться, что вы правильно обрабатываете пустые или null коллекции.


  Сведения об ответе

davran

05:02, 29th August, 2020

добро пожаловать в StackOverflow :)

Как правило, то, что вы хотели сделать, это базовая информация в выпадающем на два значения ValueMember и DisplayMember .

ValueMember-это источник фактического значения элементов управления (это будет ключевое значение в строке заказа), элемент отображения-это значение, которое отображается пользователю вместо значения (это будет значение FK).

Нет ли какой-то особой причины, по которой вы не можете просто вернуть все необходимые данные и установить эти свойства?


  Сведения об ответе

PIRLO

17:25, 6th August, 2020

Вот хорошее видео "How Do I", которое демонстрирует привязку данных:

http://windowsclient.net/learn/video.aspx?v=52579


  Сведения об ответе

pumpa

20:16, 15th August, 2020

Мой первоначальный вопрос, очевидно, не был ясен, извините за это.

Проблема была не в привязке данных к DataGridView в целом, или с реализацией DataGridViewComboBoxColumn - как справедливо говорят люди, которые уже ответили, это хорошо задокументировано в интернете.

Проблема, которую я пытаюсь решить, заключается в обновлении свойств, которые детализируются через отношения.

В моем примере ордеров, когда я изменяю значение столбца "Product", столбец "Product Type" не обновляется - даже если в коде я устанавливаю свойство и запускаю событие NotifyPropertyChanged. (В debug я хожу во все нужные места)

После долгих поисков я понял, что это даже не работает, когда я непосредственно устанавливаю свойство "Product Type" datasource, а устанавливаю его в "Product" setter.

Еще одна вещь, которая, по моему мнению, возвращает меня на правильный путь, заключается в том, что когда я предоставляю издевательский слой dataccess, созданный в основной форме, все работает нормально.

Кроме того, когда я копирую IList, сделанный nHibernate, в IBindingList - все снова кажется прекрасным.

Таким образом, проблема заключается в том, что я думаю, что потоковая обработка и события NotifyPropertyChanged теряются при использовании определенных источников данных определенным образом (жаль, что я не могу быть более точным!)

Я собираюсь продолжать исследовать лучшие способы решения этой проблемы, чем копирование IList в IBindingList - возможно, мне нужно узнать о маршалировании потоков.

Редактировать

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

Решение для доступа к данным, которое у меня сейчас есть, использует вариацию шаблона Rob Conery IRepository, возвращая мои коллекции для привязки в качестве пользовательского класса, который я создал, SortableBindingLazyList, который происходит от BindingList, реализует методы ядра сортировки, а также сохраняет свой внутренний список в виде запроса, задерживая материализацию списка.


  Сведения об ответе

Chhiki

21:06, 1st October, 2020

Ну, я не знаю, поддерживается ли он DataGridView, но когда вы делаете обычную привязку данных WinForms (скажем, к обычному TextBox), вы можете использовать пути свойств для навигации по объектным отношениям.

Что-то вроде этого:

myTextBox.DataBindings.Add("Text", anOrderLine, "OrderedPart.PartNumber");

Было бы полезно посмотреть, работает ли это и в вашей ситуации.


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться