Как запретить автоматическую прокрутку DataGridView при изменении источника данных?
-
19-09-2019 - |
Вопрос
Я попробовал это (http://brainof-dave.blogspot.com/2007/08/turning-off-auto-scrolling-in-bound.html) в событии «RowChanged» в DataTable, который является источником данных для DataGridView, но безрезультатно.
По сути, у меня есть DataGridView с BindingSource в качестве источника данных.Источник данных BindingSource — это DataView, содержащий DataTable.Каждый раз, когда данные в одной из строк изменяются, DataGridView прокручивается обратно вверх.Есть ли простое решение этой проблемы?
Решение
Кажется, я нашел это: http://seewinapp.blogspot.com/2005/09/is-your-autoscroll-too-auto.html
Я переопределил событие RowChanged в DataTable, сохранил FirstDisplayedScrollingRowIndex, вызвал метод делегата с этим индексом в качестве аргумента, а затем сбросил FirstDisplayedScrollingRowIndex на этот аргумент внутри метода делегата.Оказывается, автоматическая прокрутка не происходит до тех пор, пока не будут запущены все события, поэтому бесполезно пытаться взломать ее внутри события.Делегат работает, потому что он вызывается после событий.
Другие советы
Вот протестированный код, который восстанавливает RowIndex после изменения источника данных.Это также восстанавливает порядок сортировки и положение последней ячейки.Язык:С# 7.0.Это код, который я написал лично, с некоторой помощью поиска в Интернете.
private void UpdateDataSource()
{
SuspendLayout();
//Save last position and sort order
DataGridView g = DataGridView1;
Int32 idxFirstDisplayedScrollingRow = g.FirstDisplayedScrollingRowIndex;
SortOrder dgvLastSortDirection = g.SortOrder;
Int32 lastSortColumnPos = g.SortedColumn?.Index ?? -1;
Int32 dgvLastCellRow = g.CurrentCell?.RowIndex ?? -1;
Int32 dgvLastCellColumn = g.CurrentCell?.ColumnIndex ?? -1;
//Set new datasource
g.DataSource = myNewDataTableSource;
//Restore sort order, scroll row, and active cell
g.InvokeIfRequired( o =>
{
if(lastSortColumnPos > -1)
{
DataGridViewColumn newColumn = o.Columns[lastSortColumnPos];
switch(dgvLastSortDirection)
{
case SortOrder.Ascending:
o.Sort(newColumn, ListSortDirection.Ascending);
break;
case SortOrder.Descending:
o.Sort(newColumn, ListSortDirection.Descending);
break;
case SortOrder.None:
//No sort
break;
}
}
if(idxFirstDisplayedScrollingRow >= 0)
o.FirstDisplayedScrollingRowIndex = idxFirstDisplayedScrollingRow;
if(dgvLastCellRow>-1 && dgvLastCellColumn>-1)
o.CurrentCell = g[dgvLastCellColumn, dgvLastCellRow];
} );
ResumeLayout();
}
public static void InvokeIfRequired<T>(this T obj, InvokeIfRequiredDelegate<T> action) where T : ISynchronizeInvoke
{
if (obj.InvokeRequired)
{
obj.Invoke(action, new Object[] { obj });
}
else
{
action(obj);
}
}