我在DataTable上的“RowChanged”事件中尝试了这个(http://brainof-dave.blogspot.com/2007/08/turning-off-auto-scrolling-in-bound.html),它是DataGridView的数据源,但无济于事。
基本上,我有一个带有BindingSource的DataGridView,因为它是DataSource。 BindingSource的DataSource是一个包含DataTable的DataView。每当其中一行中的数据发生变化时,DataGridView就会滚动回到顶部。对此有一个简单的解决方法吗?
答案 0 :(得分:1)
看起来我找到了它:http://seewinapp.blogspot.com/2005/09/is-your-autoscroll-too-auto.html
我覆盖了DataTable上的RowChanged事件,存储了FirstDisplayedScrollingRowIndex,调用了以该索引作为参数的委托方法,然后将FirstDisplayedScrollingRowIndex重置为委托方法中的该参数。事实证明,直到所有事件都被触发后才会发生自动滚动,因此在事件中尝试破解它是没用的。委托是有效的,因为它是在事件之后调用的。
答案 1 :(得分:0)
这是经过测试的代码,该代码在更改数据源后可还原RowIndex。这也将恢复排序顺序和最后一个单元格的位置。语言:C#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);
}
}