Как предотвратить автоматическую прокрутку DataGridView при изменении источника данных? - PullRequest
3 голосов
/ 05 октября 2009

Я попробовал это (http://brainof -dave.blogspot.com / 2007/08 / отключение-авт-прокрутка-в-bound.html ) в событии "RowChanged" в DataTable это источник данных для DataGridView, но безрезультатно.

По сути, у меня есть DataGridView с BindingSource, поскольку это DataSource. Источник данных BindingSource - это DataView, который содержит DataTable. Каждый раз, когда данные в одной из строк меняются, DataGridView прокручивается обратно к вершине. Есть ли простое исправление для этого?

Ответы [ 2 ]

1 голос
/ 11 апреля 2019

Вот проверенный код, который восстанавливает 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);
        }
    } 
1 голос
/ 05 октября 2009

Похоже, я нашел это: http://seewinapp.blogspot.com/2005/09/is-your-autoscroll-too-auto.html

Я переопределил событие RowChanged в DataTable, сохранил FirstDisplayedScrollingRowIndex, вызвал метод делегата с этим индексом в качестве аргумента и затем сбросил FirstDisplayedScrollingRowIndex для этого аргумента внутри метода делегата. Оказывается, что автопрокрутка не происходит до тех пор, пока не сработают все события, поэтому пытаться взломать ее внутри события бесполезно. Делегат работает, потому что он вызывается после событий.

...