Исключение индекса привязки источника данных Windows DataGridView вне диапазона - PullRequest
3 голосов
/ 25 февраля 2010

Сценарий:

В основном у меня есть

  • System.Windows.Forms.DataGridView

  • Класс, который наследует BindingSource и IBindingList

  • Класс, который имеет 2 стандартных списка как частные свойства

DataGridView dgv = new ...

MyBindingSource bindingSource = new ...

MyList list = new ...

Свойство DataGridView.DataSource устанавливается на BindingSource, а свойство BindingSource.DataSource устанавливается на один из закрытых списков списка

bindingSource.DataSource = list.ListA;

dgv.DataSource = bindingSource;

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

Надеюсь, все это имело смысл, теперь проблема: После добавления одного объекта в список (не источника привязки) я хочу, чтобы элемент отображался в DataGridView. Но единственный способ, которым я в настоящее время могу заставить это работать, состоит в том, чтобы создать другой экземпляр bindingSource с добавленным новым объектом и установить DataGridView.DataSource на новый bindingSource. Это конечно ужасно неэффективно, и представление данных должно каждый раз аннулировать все это, что является хитрым.

Вместо этого я хочу, чтобы List уведомлял BindingSource, который сообщает DataGridView о добавлении нового объекта, чтобы он мог выполнять свои функции. Я пробовал это, но я продолжал получать исключение IndexOutOfrange, говорящее «Элемент с индексом -1 не имеет значения». Я посмотрел на BindingSource, и в действительности позиция была -1, а свойство Current вызвало то же исключение. Когда я создаю новый BindingSource каждый раз, когда свойства position и Current верны.

Итак, что мне нужно сделать, чтобы эти свойства обновлялись при добавлении элемента в список? Я открыл его с помощью рефлектора, чтобы увидеть, где он был установлен, и выглядел так, будто «CurrencyManager» как-то с этим связан. Я попробовал несколько вещей, таких как base.OnDataMemberChanged base.OnListChanged безрезультатно.

Редактировать: Забыл упомянуть, что я получаю исключение, только когда я щелкаю строку в представлении таблицы данных, он добавляет элементы в порядке. Так что, как будто DataGridView не синхронизирован с BindingSource

Ответы [ 3 ]

2 голосов
/ 18 мая 2010

Когда DataSource меняет свое содержимое, DataGridView очищает свою сетку и вызывает событие SelectionChanged, а другие события, связанные с взаимодействием с пользователем. Важно знать, что при возникновении события данные вообще не отображаются, поэтому, если у вас есть прослушиватель события SelectionChanged, и он обращается к строкам или столбцам внутри, он будет вызывать исключение при привязке при доступе к строкам. Решение: всегда проверяйте Rows.count на 0, прежде чем использовать любые ресурсы сетки данных. Приветствия

1 голос
/ 25 февраля 2010

Если вместо этого вы используете BindingList (универсальный), он будет уведомлять о добавлении / удалении элементов, а также об изменениях отдельных элементов. (http://msdn.microsoft.com/en-us/library/ms132679.aspx)

1 голос
/ 25 февраля 2010

Рассматривали ли вы использование ObservableCollection ? Всякий раз, когда есть элементы, добавленные или удаленные из коллекции, он уведомит элемент управления, его привязка к которому обновлена. То же самое можно сказать и о свойствах элементов в коллекции (хотя вы должны вызывать событие вручную)

Я не уверен, что может быть причиной исключения

...