3

我在作为数据源的 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 都会滚动回顶部。有一个简单的解决方法吗?

4

2 回答 2

1

看起来我找到了它:http ://seewinapp.blogspot.com/2005/09/is-your-autoscroll-too-auto.html

我覆盖了 DataTable 上的 RowChanged 事件,存储了 FirstDisplayedScrollingRowIndex,以该索引作为参数调用了委托方法,然后将 FirstDisplayedScrollingRowIndex 重置为委托方法内的该参数。事实证明,直到所有事件都被触发后才会发生自动滚动,因此尝试在事件中破解它是没有用的。委托之所以有效,是因为它是在事件之后调用的。

于 2009-10-05T18:02:10.477 回答
1

这是在更改数据源后恢复 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);
        }
    } 
于 2019-04-10T23:30:24.523 回答