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
我做了类似的事情
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;
};