Привязка данных WinForms и отношения внешнего ключа

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

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

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

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

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

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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
0
4 570
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Ответ принят как подходящий

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

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

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

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

David Hall 12.11.2008 08:03

Другие вопросы по теме