重载DataGridView后如何保存位置

时间:2010-03-14 14:12:35

标签: c# winforms datagridview

这是我的代码:

        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 个答案:

答案 0 :(得分:36)

这是我提出的解决方案。如果行数没有很大差异,则不需要选择行并在刷新后将滚动条放回同一区域。

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;

答案 1 :(得分:4)

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

答案 2 :(得分:3)

您可以在使用DataGridView.CurrentRow启动getData之前保存选定的行,并在加载网格后选择该行。

this question中,我回答了如何在DataGridView中选择特定行。


编辑:我认为您使用的是WinForms

Edit2:滚动条怎么样?

您也可以使用此声明保存第一个可见行索引

DataGridView.FirstDisplayedCell.RowIndex

答案 3 :(得分:2)

@ 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;

答案 4 :(得分:1)

在另一个论坛上,我找到了一个没有任何操纵的解决方案:

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

答案 5 :(得分:0)

目前,您每次加载页面时都要加载数据。我建议使用Page.IsPostback属性来检查它是否是回发。

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

这将减少您的数据库上的负载量,并将退出导致您的选择出现问题。

答案 6 :(得分:0)

这样做是因为您正在重置或重新生成DataGridView控件的DataSource属性。

为了执行您希望的操作,您必须在重置DataGridView的DataSource属性之前将CurrentItem索引保存到本地变量中。但是,这样做意味着您知道您将拥有相同或更多的数据,否则您将会遇到一个IndexOutOfRangeException尝试移动到比DataGridView中实际包含的数据量更大的索引。

因此,如果您希望保存行或单元格的索引,则需要通过DataGridView控件属性进行保存,因为BindingSource不会提供此类功能。

  

在DataGridView中,选定的行   和当前行(由一个表示   行标题中的箭头可能不是   同一排。另外,我们可以   在DataGridView中选择多个行   但是当前行只能是一行   行。当SelectionMode属性时   DataGridView的设置为   FullRowSelect,当前行将是   总是选择。如果你愿意的话   更改a中的当前行   DataGridView控件,你可以设置   CurrentCell属性

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

如果您只想更改所选行,可以将所需行的Selected属性设置为true。

dataGridView1.CurrentRow.Selected = false; 
dataGridView1.Rows[1].Selected = true; 

答案 7 :(得分:0)

我做了这样的事情。

  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];
    }
    

答案 8 :(得分:0)

我们可以使用SelectionChanged的{​​{1}}事件来跟踪选定的行。问题是当重新绑定数据源时,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

答案 9 :(得分:0)

我无法使用它来处理大型数据集。 我这样做后,该职位已重置:

saveRow = dataGridView1.FirstDisplayedScrollingRowIndex;
*** refresh data ***
dataGridView1.FirstDisplayedScrollingRowIndex = saveRow;
*** Now we still got a reset ***

可能是因为在重置saveRow之前未加载数据集。

对我有用的解决方案是重置 DataBindingComplete 事件中的位置,如下所示:

        dataGridView1.DataBindingComplete += (o, args) =>
        {
            if(dataGridView1.RowCount > 0 && saveRow < dataGridView1.RowCount && saveRow > 0)
                dataGridView1.FirstDisplayedScrollingRowIndex = saveRow;
        };