Как сохранить позицию после перезагрузки DataGridView - PullRequest
16 голосов
/ 14 марта 2010

это мой код:

        private void getData(string selectCommand)
    {
        string connectionString = @"Server=localhost;User=SYSDBA;Password=masterkey;Database=C:\data\test.fdb";

        dataAdapter = new FbDataAdapter(selectCommand, connectionString);
        DataTable data = new DataTable();
        dataAdapter.Fill(data);
        bindingSource.DataSource = data;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        getData(dataAdapter.SelectCommand.CommandText);
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        dataGridView1.DataSource = bindingSource;
        getData("SELECT * FROM cities");
    }

после перезагрузки данных при нажатии кнопки 1 выбор ячейки переходит на первый столбец и полосы прокрутки сбрасываются. Как сохранить позицию DataGridView?

Ответы [ 10 ]

36 голосов
/ 14 марта 2012

Вот решение, которое я придумал. Не требует выбора строки и помещает полосу прокрутки обратно в ту же область после обновления при условии, что количество строк не сильно меняется.

int saveRow = 0;
if (dataGridView1.Rows.Count > 0 && dataGridView1.FirstDisplayedCell != null)
    saveRow = dataGridView1.FirstDisplayedCell.RowIndex;

dataGridView1.DataSource = dataTable1;

if (saveRow != 0 && saveRow < dataGridView1.Rows.Count)
    dataGridView1.FirstDisplayedScrollingRowIndex = saveRow;
4 голосов
/ 09 июля 2013
int FirstDisplayedScrollingRowIndex = this.dgvItems.FirstDisplayedScrollingRowIndex; //Save Current Scroll Index
int SelectedRowIndex = 0;
if (this.dgvItems.SelectedRows.Count > 0) SelectedRowIndex = this.dgvItems.SelectedRows[0].Index; //Save Current Selected Row Index

//REFRESH DataGridView HERE

if ((FirstDisplayedScrollingRowIndex >=0) && ((this.dgvItems.Rows.Count -1) >= FirstDisplayedScrollingRowIndex)) this.dgvItems.FirstDisplayedScrollingRowIndex = FirstDisplayedScrollingRowIndex; //Restore Scroll Index
if ((this.dgvItems.Rows.Count -1) >= SelectedRowIndex) this.dgvItems.Rows[SelectedRowIndex].Selected = true; //Restore Selected Row
3 голосов
/ 20 декабря 2015

Простой способ - код удара:

int CurrentRowIndex = (hSuperGrid1.CurrentRow.Index);

////after Fill The DataGridView

hSuperGrid1.ClearSelection();
hSuperGrid1.CurrentRow.Selected = false;

hSuperGrid1.Rows[CurrentRowIndex].Selected = true;

hSuperGrid1.CurrentCell = hSuperGrid1[0, CurrentRowIndex];
3 голосов
/ 14 марта 2010

Вы можете сохранить выбранную строку перед запуском getData, используя DataGridView.CurrentRow, и выбрать эту строку после загрузки Grid.

В этот вопрос Я ответил, как выбрать конкретную строку в DataGridView.


Редактировать: Я предполагал, что вы используете WinForms

Edit2: А что с полосами прокрутки?

Вы также можете сохранить первый видимый индекс строки с помощью этого оператора

DataGridView.FirstDisplayedCell.RowIndex
2 голосов
/ 06 апреля 2017

@ Ответ ovinophile помог, конечно, но он не касался горизонтальной прокрутки DataGridView для меня. В дополнение к ответу @ ovinophile, это хорошо работает для поддержания горизонтальной и вертикальной позиции прокрутки:

// Remember the vertical scroll position of the DataGridView
int saveVScroll = 0;
if (DataGridView1.Rows.Count > 0)
    saveVScroll = DataGridView1.FirstDisplayedCell.RowIndex;

// Remember the horizontal scroll position of the DataGridView
int saveHScroll = 0;
if (DataGridView1.HorizontalScrollingOffset > 0)
    saveHScroll = DataGridView1.HorizontalScrollingOffset;

// Refresh the DataGridView
DataGridView1.DataSource = ds.Tables(0);

// Go back to the saved vertical scroll position if available
if (saveVScroll != 0 && saveVScroll < DataGridView1.Rows.Count)
    DataGridView1.FirstDisplayedScrollingRowIndex = saveVScroll;

// Go back to the saved horizontal scroll position if available
if (saveHScroll != 0)
    DataGridView1.HorizontalScrollingOffset = saveHScroll;
1 голос
/ 14 марта 2010

На другом форуме я нашел решение без всяких манипуляций:

    private void getData(string selectCommand)
    {
        string connectionString = @"Server=localhost;User=SYSDBA;Password=masterkey;Database=C:\data\test.fdb";

        dataAdapter = new FbDataAdapter(selectCommand, connectionString);
        data = new DataTable();
        dataAdapter.Fill(data);
        bindingSource.DataSource = data;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        dataAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
        dataAdapter.Fill(data);
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        dataGridView1.DataSource = bindingSource;
        getData("SELECT * FROM cities");
    }
0 голосов
/ 31 октября 2018

Мы можем использовать SelectionChanged событие DataGridView для отслеживания выбранной строки. Проблема в том, что при повторном связывании источника данных CurrentRow.Index сбрасывается в ноль.

Мы можем справиться с этим, отсоединившись от события SelectionChanged перед привязкой нашего источника данных и повторно подключив его к событию после привязки нашего источника данных.

// Detach Event
dataGridView1.SelectionChanged -= dataGridView1_SelectionChanged;
// Bind Data
bindingSource.DataSource = data; // or dataGridView1.DataSource = data;
// Set Selected Row
dataGridView1.Rows[LastSelectedRowIndex].Selected = true;
// Re-attach Event
dataGridView1.SelectionChanged += dataGridView1_SelectionChanged;

Событие для отслеживания выбранного индекса простое.

int LastSelectedRowIndex = 0;
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
     LastSelectedRowIndex = dataGridView1.CurrentRow.Index;  
}

Это должно дать вам представление о концепции.

Сохранение выбора с уникальным значением ключа

Обычно, когда мы привязываем информацию к источнику данных, это происходит потому, что информация изменилась. Если размер набора данных изменился, это означает, что ваши индексы строк также изменятся.

Вот почему мы не должны полагаться на LastSelectedRowIndex для поддержки выбранной строки. Вместо этого мы должны использовать уникальный ключ в источнике данных.

Наше SelectionChanged событие становится следующим.

// KeyIndex is the Unique Key column within your dataset.
int KeyIndex = 2;
string LastSelectedKey = string.Empty;
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
     LastSelectedKey = dataGridView1.CurrentRow.Cells[KeyIndex].Value.ToString();
}

И вместо установки DataGridView выбранной строки по индексу мы можем установить ее по значению ключа.

// Set Selected Row
// If we need to scroll the selected row into view
// this would be a good place to set FirstDisplayedScrollingRowIndex
foreach (DataGridViewRow row in dataGridView1.Rows)
     if (row.Cells[KeyIndex].Value.ToString() == LastSelectedKey)
          row.Selected = true;
0 голосов
/ 25 октября 2018

Я сделал что-то подобное.

  1. Сохранить FirstDisplayedCell и CurrentCell выбран
  2. Обновить
  3. Установить dataGridView предыдущей строки и установить предыдущую выбранную строку

    // Объявление переменных int rowIndex = 0; int saveRow = 0;

    if(dataGridView1.SelectedRows.Count > 0)
    {
        rowIndex = dataGridView1.CurrentCell.RowIndex;
        saveRow = dataGridView1.FirstDisplayedCell.RowIndex;
    }
    
    //REFRESH CODE HERE
    
    if(dataGridView1.SelectedRows.Count > 0)
    {
        dataGridView1.FirstDisplayedScrollingRowIndex = saveRow;
        dataGridView1.CurrentCell = dataGridView1.Rows[rowIndex].Cells[0];
    }
    
0 голосов
/ 14 марта 2010

Это происходит потому, что вы сбрасываете или изменяете свойство DataSource элемента управления DataGridView.

Чтобы выполнить то, что вы хотите, вы должны сохранить индекс CurrentItem в локальную переменную перед сбросом свойства DataSource вашего DataGridView. Однако при этом подразумевается, что вы знаете, что у вас будет такой же или более объем данных, в противном случае вы получите исключение IndexOutOfRangeException, пытаясь перейти к большему индексу, чем объем данных, фактически содержащийся в вашем DataGridView. *

Итак, если вы хотите сохранить индекс своей строки или ячейки, вам нужно будет сделать это через свойства элемента управления DataGridView, поскольку ваш BindingSource не будет предоставлять такую ​​функцию.

В DataGridView выбранная строка и текущий ряд (обозначенный стрелка в заголовке строки) не может быть тот же ряд. Кроме того, мы могли бы выбрать несколько строк в DataGridView но текущий ряд может быть только один строка. Когда свойство SelectionMode DataGridView установлен в FullRowSelect, текущая строка будет всегда выбран. Если вы хотите изменить текущую строку в Элемент управления DataGridView, вы можете установить Свойство CurrentCell

dataGridView1.CurrentCell = dataGridView1.Rows[1].Cells[0]; 

Если вы хотите просто изменить выбранную строку, вы можете установить для свойства Selected строки, которую хотите установить, значение true.

dataGridView1.CurrentRow.Selected = false; 
dataGridView1.Rows[1].Selected = true; 
0 голосов
/ 14 марта 2010

В настоящее время вы загружаете данные каждый раз при загрузке страницы. Я бы предложил использовать свойство Page.IsPostback, чтобы проверить и проверить, является ли это обратной передачей.

if(!Page.IsPostback)
{
    dataGridView1.DataSource = bindingSource;  
    getData("SELECT * FROM cities");
}

Это уменьшит нагрузку на вашу БД и прекратит вызывать проблемы с вашими выборами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...