INotifyPropertyChanged или INotifyCollectionChanged с DataTable?

#wpf #binding #inotifypropertychanged #inotifycollectionchanged

#wpf #привязка #inotifypropertychanged #inotifycollectionchanged

Вопрос:

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

Как это сделать? С помощью INotifyPropertyChanged или с помощью INotifyCollectionChanged ?

Примечание: Я пытаюсь с помощью INotifyPropertyChanged , но он обнаруживает только тогда, когда я устанавливаю некоторое значение в DataTable, и никогда, когда я изменяю какое-либо значение любой ячейки в DataGrid, я уже пробовал OneWay и TwoWay , но ничего не происходит.

Заранее спасибо!

Ответ №1:

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

INotifyCollectionChanged Это интерфейс, который должна реализовать коллекция, и предназначен для уведомлений о событиях добавления и удаления.

Смотрите раздел «Как реализовать коллекции» на этой странице.


Вот способ подойти к вашей проблеме:

  • Создайте новый класс, который предоставляет свойства, которые в данный момент хранятся в каждом DataRow . В этом классе реализуют INotifyPropertyChanged .
  • Вместо DataTable используйте ObservableCollection<T> an или ваш новый класс.

ObservableCollection уже реализовано INotifyCollectionChanged , так что это экономит ваши усилия по его самостоятельной реализации.

Комментарии:

1. Итак, если я правильно понимаю, мне придется превратить мою DataTable в IEnumarable, верно? И тогда мне придется реализовывать уведомления о коллекциях, когда что-то вставляется или удаляется. Но без реального примера использования INotifyCollectionChanged это сложно. Я уже понимаю, как работать с INotifyPropertyChanged, но с коллекциями я не нашел ни одного хорошего примера.

2. @Miguel — Я добавил дополнительный абзац, чтобы ответить на ваши вопросы.

3. не знаю, почему кто-то проголосовал против меня, но я просто добавлю кое-что к этому ответу. нет необходимости создавать observablecollection. я использую datagrid с itemssource для datatable повсюду в моем проекте, я могу добавлять, изменять, удалять содержимое, проводить проверку и фильтрацию, и все это без переноса моей datatable. кстати, я все еще не знаю, ПОЧЕМУ Мигель хочет знать, когда изменяется какая-либо ячейка. существует свойство Hashchanges, которое сообщает вам, когда происходит изменение.

Ответ №2:

если вы установите для itemssource вашей сетки данных значение datatable, то wpf создаст IBindingListView, который привязан к сетке данных.

что вы можете сделать сейчас, так это редактировать, добавлять и удалять элементы в свой datatable с помощью datagrid. если вы хотите знать, когда изменяется ячейка в вашей datatable, вы можете подписаться на DataTable.Событие ColumnChanged.

почему вы хотите знать, когда изменяется ячейка?

Комментарии:

1. Если вы программно изменяете ячейку в вашей datatable, то это изменение автоматически отражается на дисплее datagrid?

Ответ №3:

Ответ на заголовок вашего вопроса: ни то, ни другое. На самом деле вам не нужно привязывать DataTable к DataGrid. Вы привязываете DataView. «The ADO.NET DataView реализует интерфейс IBindingList, который предоставляет уведомления об изменениях, которые прослушивает механизм привязки.»(Обзор источников привязки) Один из ответов на ваш вопрос: вы изменяете ячейку datagrid с помощью текстового поля (обычно). Сделайте это с новым текстовым полем, наследуемым от TextBox, и переопределите его методы OnGotFocus и OnLostFocus.