Привязка данных WinForms и отношения внешних ключей - PullRequest
6 голосов
/ 27 августа 2008

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

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

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

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

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

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

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

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

Ответы [ 5 ]

2 голосов
/ 11 ноября 2008

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

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

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

1 голос
/ 27 августа 2008

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

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

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

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

0 голосов
/ 22 октября 2008

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

Примерно так:

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

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

0 голосов
/ 01 сентября 2008

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

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

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

В моем примере заказов, когда я изменяю значение столбца «Продукт», столбец «Тип продукта» не обновляется - даже если в коде я устанавливаю свойство и запускаю событие NotifyPropertyChanged. (В отладке я иду во все нужные места)

После долгих раздумий я понял, что это даже не сработало, когда я непосредственно установил свойство «Тип продукта» источника данных, а не установил его в установщике «Продукт».

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

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

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

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

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

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

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

0 голосов
/ 27 августа 2008

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...