C# 如何在重新加载DataGridView后保存位置

C# 如何在重新加载DataGridView后保存位置,c#,winforms,datagridview,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)

这是我的代码:

        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的位置?

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

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


编辑:我以为您正在使用WinForms

Edit2:那么滚动条呢

您也可以使用此语句保存第一个可见的行索引

DataGridView.FirstDisplayedCell.RowIndex

当前,每次加载页面时都会加载数据。我建议使用Page.IsPostback属性检查是否为回发

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

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

这是因为您正在重置或重新影响DataGridView控件的DataSource属性

为了执行所需操作,必须在重置DataGridView的DataSource属性之前将CurrentItem索引保存到局部变量中。但是,这样做意味着您知道您将拥有相同或更多的数据量,否则您将出现IndexOutOfRangeException,试图移动到比DataGridView中实际包含的数据量更大的索引

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

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

如果只想更改选定的行,可以将要更改的行的selected属性设置为true

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

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

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

这是我想出的解决办法。不需要选择行,并在刷新后将滚动条放回同一区域,前提是行数变化不大

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;
int saveRow=0;
如果(dataGridView1.Rows.Count>0&&dataGridView1.FirstDisplayedCell!=null)
saveRow=dataGridView1.FirstDisplayedCell.RowIndex;
dataGridView1.DataSource=dataTable1;
if(saveRow!=0&&saveRow
简单的方法是吹代码:

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

@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;
//记住DataGridView的垂直滚动位置
int saveVScroll=0;
如果(DataGridView1.Rows.Count>0)
saveVScroll=DataGridView1.FirstDisplayedCell.RowIndex;
//记住DataGridView的水平滚动位置
int saveHScroll=0;
如果(DataGridView1.HorizontalScrollingOffset>0)
saveHScroll=DataGridView1.HorizontalScrollingOffset;
//刷新DataGridView
DataGridView1.DataSource=ds.Tables(0);
//返回保存的垂直滚动位置(如果可用)
if(saveVScroll!=0&&saveVScroll
我做了类似的事情

  • 保存FirstDisplayedCell和CurrentCell selected
  • 刷新
  • 设置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];
    }
    

  • 我们可以使用
    DataGridView
    SelectionChanged
    事件来跟踪所选行。问题是当重新绑定数据源时,
    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
    来维护所选行的原因。相反,我们应该在数据源中使用唯一的键

    // 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;
    
    我们的
    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
    selectedrow-by-index,而不是设置
    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;
    

    我无法将其用于大型数据集。 在我执行以下操作后,位置被重置:

    saveRow = dataGridView1.FirstDisplayedScrollingRowIndex;
    *** refresh data ***
    dataGridView1.FirstDisplayedScrollingRowIndex = saveRow;
    *** Now we still got a reset ***
    
    可能是因为在我重置存储行之前没有加载数据集

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

            dataGridView1.DataBindingComplete += (o, args) =>
            {
                if(dataGridView1.RowCount > 0 && saveRow < dataGridView1.RowCount && saveRow > 0)
                    dataGridView1.FirstDisplayedScrollingRowIndex = saveRow;
            };
    
    dataGridView1.DataBindingComplete+=(o,args)=>
    {
    如果(dataGridView1.RowCount>0&&saveRow0)
    dataGridView1.FirstDisplayedScrollingRowIndex=saveRow;
    };
    
    此Page.IsPostback属性仅对ASP.NET应用程序有效。我们在这里讨论的是WinForms。滚动条呢?如果用户只需滚动datagrid而不选择单元格。Th
            dataGridView1.DataBindingComplete += (o, args) =>
            {
                if(dataGridView1.RowCount > 0 && saveRow < dataGridView1.RowCount && saveRow > 0)
                    dataGridView1.FirstDisplayedScrollingRowIndex = saveRow;
            };