Хорошо, поэтому краткий ответ на мою проблему заключался в замене реализаций таблицы данных для BindingSource.В прошлом я сталкивался с несколькими другими проблемами, которые были решены простым использованием компонента BindingSource.В документации действительно говорится, что DataGridView спроектирован так, чтобы работать очень близко с BindingSources, и мой опыт подтверждает это.
Причина, по которой это работает, заключается в том, что DataGridView внутренне использует CurrencyManager для отслеживания положения строки.Хотя я полагал, что этот диспетчер валют обернет источник данных, который я также связал с сеткой, что в некоторой степени и делает, он не зависает и не завершает редактирование текущей строки при использовании источника данных в качестве источника данных.
Так что я предполагаю, что это потому, что таблица не запускает ожидаемые события /, возможно, не реализует соответствующие интерфейсы.
Detail:
Используя Redgate Reflector, я смог углубиться в элемент управления DataGridView.DataGridView использует пару внутренних классов, к которым вы просто не можете получить доступ из своего собственного кода, наиболее важным из которых (для рассматриваемой проблемы) является:
internal class DataGridViewDataConnection
В этом классе есть длинный метод, называемый:
private void ProcessListChanged(ListChangedEventArgs e)
Важной частью этого метода является следующая:
if ((this.owner.NewRowIndex != -1) && (e.NewIndex == this.owner.Rows.Count))
{
throw new InvalidOperationException();
}
this.owner.Rows.InsertInternal(e.NewIndex, this.owner.RowTemplateClone, true);
Label_05B4:
if (((this.owner.Rows.Count > 0) && !this.dataConnectionState[8]) && !this.owner.InSortOperation)
{
this.MatchCurrencyManagerPosition(false, e.ListChangedType == ListChangedType.Reset);
}
}
finally
{
this.dataConnectionState[0x10] = false;
}
Вы можете видеть, что метод this.MatchCurrencyManagerPosition перемещает текущую позицию строки новой строки в конецсетка, как показано ниже:
public void MatchCurrencyManagerPosition(bool scrollIntoView, bool clearSelection)
{
if (this.owner.Columns.Count != 0)
{
int columnIndex = (this.owner.CurrentCellAddress.X == -1) ? this.owner.FirstDisplayedColumnIndex : this.owner.CurrentCellAddress.X;
if (columnIndex == -1)
{
DataGridViewColumn firstColumn = this.owner.Columns.GetFirstColumn(DataGridViewElementStates.None);
firstColumn.Visible = true;
columnIndex = firstColumn.Index;
}
int position = this.currencyManager.Position;
if (position == -1)
{
if (!this.owner.SetCurrentCellAddressCore(-1, -1, false, false, false))
{
throw new InvalidOperationException(SR.GetString("DataGridView_CellChangeCannotBeCommittedOrAborted"));
}
}
else if (position < this.owner.Rows.Count)
{
if ((this.owner.Rows.GetRowState(position) & DataGridViewElementStates.Visible) == DataGridViewElementStates.None)
{
this.owner.Rows[position].Visible = true;
}
if (((position != this.owner.CurrentCellAddress.Y) || (columnIndex != this.owner.CurrentCellAddress.X)) && ((scrollIntoView && !this.owner.ScrollIntoView(columnIndex, position, true)) || (((columnIndex < this.owner.Columns.Count) && (position < this.owner.Rows.Count)) && !this.owner.SetAndSelectCurrentCellAddress(columnIndex, position, true, false, false, clearSelection, false))))
{
throw new InvalidOperationException(SR.GetString("DataGridView_CellChangeCannotBeCommittedOrAborted"));
}
}
}
}
Это была проблема, которую мне нужно было решить, поскольку строки (строки), вводимые через триггер, зависали в строке новой строки, и я просто не мог найти подходящее событиезавершить блокировку редактирования при использовании таблиц данных и, как указано выше, эти методы были недоступны для моего кода.
Как только я увидел, что внутри DataGridView используется менеджер валют, я решил попробовать замену источника привязки для таблиц данных, что решило проблему.