开发者

How do I prevent a DataGridView from autoscrolling when the datasource changes?

开发者 https://www.devze.com 2022-12-08 06:15 出处:网络
I tried this (http://brainof-dave.blogspot开发者_如何学Go.com/2007/08/turning-off-auto-scrolling-in-bound.html) in the \"RowChanged\" event on the DataTable that is the data source for the DataGridVie

I tried this (http://brainof-dave.blogspot开发者_如何学Go.com/2007/08/turning-off-auto-scrolling-in-bound.html) in the "RowChanged" event on the DataTable that is the data source for the DataGridView, but to no avail.

Basically, I have a DataGridView with a BindingSource as it's DataSource. The BindingSource's DataSource is a DataView that contains a DataTable. Every time data in one of the rows changes, the DataGridView scrolls back to the top. Is there a simple fix for this?


Looks like I found it: http://seewinapp.blogspot.com/2005/09/is-your-autoscroll-too-auto.html

I overrode the RowChanged event on the DataTable, stored the FirstDisplayedScrollingRowIndex, invoked a delegate method with that index as the argument, and then reset the FirstDisplayedScrollingRowIndex to that argument inside the delegate method. It turns out that auto-scroll doesn't occur until after all events have been fired, so it's useless to try to hack it inside an event. The delegate works because it is invoked after the events.


Here is tested code that restores the RowIndex after changing the datasource. This also restores the sort order and last cell position. Language: C# 7.0. This is code I wrote personally, with some help from web searches.

    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);
        }
    } 
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号