У меня довольно сложное приложение WinForms, которое использует привязку данных для привязки строго типизированных DataTables к элементам управления (не уверен, что этот факт имеет значение здесь). Исключение возникает, когда изменение столбца запускает логику, которая обновляет другой столбец в той же строке (или, по крайней мере, это моя теория).
Пример: запись о клиенте привязана к ComboBox со списком контактов с Customer :: MarketingContactId. Когда контакт изменится, появятся несколько текстовых полей и флажков, которые будут обновлены, чтобы можно было редактировать данные этого контакта. Один из этих флажков имеет обработчик события CheckChanged
void MarketingContactIsFulltimeChangedHandler(object sender, EventArgs e)
{
var contact = m_row.MarketingContact;
if (contact != null && contact.IsFullTimeEmployee)
{
var i = m_row.Institution;
if (i.CreditLevel > m_row.CreditLevel)
m_row.CreditLevel = i.CreditLevel;
}
}
m_row - Клиент, получающий обновления. Ошибка не возникает в этом коде, но на самом деле возникает из настройки поля MarketingContactId. Вот стек вызовов, который подтверждает это:
System.Data.dll! System.Data.DataView.OnListChanged (System.ComponentModel.ListChangedEventArgs
e = {System.ComponentModel.ListChangedEventArgs}) Строка 1433 + 0x2c
байты C #
System.Data.dll! System.Data.DataView.IndexListChanged (отправитель объекта, System.ComponentModel.ListChangedEventArgs e =
{System.ComponentModel.ListChangedEventArgs}) Строка 1299 C #
System.Data.dll! System.Data.DataView.IndexListChangedInternal (System.ComponentModel.ListChangedEventArgs
д) Строка 1324 С #
System.Data.dll! System.Data.DataViewListener.IndexListChanged (System.ComponentModel.ListChangedEventArgs
д) Строка 76 + 0x7 байтов C #
System.Data.dll! System.Data.Index.OnListChanged.AnonymousMethod (System.Data.DataViewListener
слушатель, System.ComponentModel.ListChangedEventArgs args, bool arg2,
bool arg3) Строка 803 + 0x7 байт C #
System.Data.dll! System.Data.Listeners.Notify (System.ComponentModel.ListChangedEventArgs
arg1 = {System.ComponentModel.ListChangedEventArgs}, bool arg2 =
false, bool arg3 = false,
System.Data.Listeners.Action
action = {Method = {Void
b__2 (System.Data.DataViewListener,
System.ComponentModel.ListChangedEventArgs, Boolean, Boolean)}}) Строка
1029 + 0x1a байт C #
System.Data.dll! System.Data.Index.OnListChanged (System.ComponentModel.ListChangedEventArgs
д) Линия 805 С #
System.Data.dll! System.Data.Index.OnListChanged (System.ComponentModel.ListChangedType
changeType, int newIndex, int oldIndex) Строка 788 C #
System.Data.dll! System.Data.Index.RecordStateChanged (int oldRecord,
System.Data.DataViewRowState oldOldState, System.Data.DataViewRowState
oldNewState, int newRecord, System.Data.DataViewRowState newOldState,
System.Data.DataViewRowState newNewState) Строка 903 + 0x10 байт C #
System.Data.dll! System.Data.DataTable.RecordStateChanged (int record1 =
0, System.Data.DataViewRowState oldState1 = Добавлено,
System.Data.DataViewRowState newState1 = Нет, int record2 = 1,
System.Data.DataViewRowState oldState2 = Нет,
System.Data.DataViewRowState newState2 = Добавлено) Строка 3473 + 0x18 байт
C #
System.Data.dll! System.Data.DataTable.SetNewRecordWorker (System.Data.DataRow
row = "CustomerRow: Id: -1", int предлагаемый Record,
System.Data.DataRowAction action = Change, bool isInMerge, int
position, bool fireEvent = true, out System.Exception
deferredException = null) Строка 3935 + 0x16 байт C #
System.Data.dll! System.Data.DataTable.SetNewRecord (System.Data.DataRow
row, int предлагаемый Record, действие System.Data.DataRowAction, bool
isInMerge, bool fireEvent) Строка 3824 C #
System.Data.dll! System.Data.DataRow.SetNewRecord (int record) Строка 1160
C # System.Data.dll! System.Data.DataRow.EndEdit () Строка 631 + 0xa
байты C #
System.Data.dll! System.Data.DataRow.this [System.Data.DataColumn] .set (System.Data.DataColumn
столбец, значение объекта) Строка 343 C #
Там указаны номера строк, так как у меня есть символы, загруженные для System.Data.dll из функции MS Symbol Server в Visual Studio. Наличие этих данных позволяет мне дополнительно отслеживать ошибку в этой части метода OnListChanged:
// snippet from System.Data.DataView::OnListChanged(ListChangedEventArgs e)
if (onListChanged != null) {
if ((col != null) && (e.NewIndex == e.OldIndex)) {
ListChangedEventArgs newEventArg = new ListChangedEventArgs(e.ListChangedType, e.NewIndex, new DataColumnPropertyDescriptor(col));
/*Here is where VS breaks for the exception*/ onListChanged(this, newEventArg);
} else {
onListChanged(this, e);
}
}
Очевидно, что что-то пошло не так, если только после проверки onListChanged! = Null это так. Я подозреваю, что обновление DataRow во время метода EndEdit вызывает это. Конечно, простая песочница, чтобы изолировать эту проблему, не отображала ошибку для меня. Кто-нибудь еще на SO сталкивался с этой ошибкой, и если да, то как вы ее исправили?
На данный момент я хочу вызвать BeginInvoke в MarketingContactIsFulltimeChangedHandler для другого метода, который выполняет логику CreditLevel.