这是我的代码:
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的位置?
答案 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)
我做了这样的事情。
设置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;
};