优雅地刷新DataGridView中的数据
本文关键字:数据 DataGridView 刷新 | 更新日期: 2023-09-27 18:00:40
我在Windows窗体中有一个DataGridView,这个网格包含接近实时的数据——我希望它至少每20秒更新一次。我的网格绑定到我用程序生成的DataTable,所以我现在有一个计时器来生成这个DataTable,并每20秒将其分配给网格。
但我遇到的问题是,当数据刷新时,网格上的任何选择或排序都会消失,这是一个很大的可用性问题。有没有其他方法可以刷新网格的内容,保留选择/排序?
恢复排序顺序和行选择的粗略指南。
在刷新之前执行此操作:
// Store the sort details.
ListSortDirection oldSortOrder;
switch (uiGrid.SortOrder)
{
case SortOrder.Ascending:
oldSortOrder = ListSortDirection.Ascending;
break;
case SortOrder.Descending:
oldSortOrder = ListSortDirection.Descending;
break;
default:
oldSortOrder = ListSortDirection.Ascending;
break;
}
DataGridViewColumn oldSortColumn = uiGrid.SortedColumn;
// Store the selected rows
List<String> selectedRows = new List<String>();
foreach (DataGridViewRow row in uiGrid.SelectedRows)
{
selectedRows.Add(row.Cells["SomeIndexColumn"].Value.ToString());
}
刷新后执行此操作:
// Restore the sort
uiGrid.Sort(oldSortColumn, oldSortOrder);
// Restore Selected rows
foreach (DataGridViewRow row in uiGrid.SelectedRows)
{
if (selectedRows.Contains(row.Cells["SomeIndexColumn"].Value.ToString()))
{
row.Selected = true;
}
}
您需要保存您的选择,然后重新加载数据并重新应用保存的选择。
这实际上是一个相当简单的过程,但我并没有用Winforms编写代码来给出一个完整的示例,但过程与类似;
在DataGridViewItems中循环。存储索引和/或键以及选择条件。
重新加载数据。
在DataGridViewItems中循环。检索索引/键匹配并应用的存储选择条件。
为什么如此频繁地刷新数据?有很多变化吗?插入?
在插入的情况下,只使用新记录更新网格就足够了,只需将它们附加到网格的行集合即可。
我喜欢Martin的回答。然而,我发现在刷新数据源后,变量oldSortColumn不知何故发生了变化,数据网格视图在"uiGrid.Sort(oldSortClumn,oldSortOrder)"中不接受它。此外,uiGrid.Sort不喜欢oldSortColumn为null。如果有人能告诉我oldSortColumn更改的原因,我将不胜感激。我决定使用排序列索引,而不是排序列本身。因此,这里是我稍微修改过的版本:
在刷新之前执行此操作:
public static void GetDataGridViewUIInfo(this DataGridView dgv, out List<int> selectedIndices,
out int? sortColumnIndex, out ListSortDirection sortOrder)
{
selectedIndices = dgv.GetSelectedRowIndices();
dgv.GetSortInfo(out sortColumnIndex, out sortOrder);
}
static List<int> GetSelectedRowIndices(this DataGridView dgv)
{
List<int> selectedIndices = new List<int>();
foreach (DataGridViewRow row in dgv.SelectedRows)
{
selectedIndices.Add(row.Index);
}
return selectedIndices;
}
static void GetSortInfo(this DataGridView dgv, out int? sortColumnIndex, out ListSortDirection sortOrder)
{
// Store the sort details
switch (dgv.SortOrder)
{
case SortOrder.Ascending:
sortOrder = ListSortDirection.Ascending;
break;
case SortOrder.Descending:
sortOrder = ListSortDirection.Descending;
break;
default:
sortOrder = ListSortDirection.Ascending;
break;
}
sortColumnIndex = dgv.SortedColumn == null ? null : (int?)dgv.SortedColumn.Index;
}
刷新后执行此操作:
public static void SetDataGridViewUIInfo(this DataGridView dgv, List<int> selectedIndices,
int? sortColumnIndex, ListSortDirection sortOrder)
{
dgv.SetSelectedRowIndices(selectedIndices);
dgv.SetSortInfo(sortColumnIndex, sortOrder);
}
static void SetSelectedRowIndices(this DataGridView dgv, List<int> selectedIndices)
{
if (dgv.Rows.Count <= 0)
// Early out if there is no row in the data grid view
return;
foreach (DataGridViewRow row in dgv.Rows)
{
row.Selected = false;
}
foreach (int index in selectedIndices)
{
if (index < dgv.Rows.Count)
dgv.Rows[index].Selected = true;
else
dgv.Rows[dgv.Rows.Count - 1].Selected = true;
}
if (selectedIndices.Count > 0 && selectedIndices[0] < dgv.Rows.Count && dgv.DataSource is BindingSource)
((BindingSource)dgv.DataSource).Position = selectedIndices[0];
}
static void SetSortInfo(this DataGridView dgv, int? sortColumnIndex, ListSortDirection sortOrder)
{
if (sortColumnIndex == null)
// Early out if there was no column used to sort in the data grid view
return;
// Restore the sort details
dgv.Sort(dgv.Columns[(int)sortColumnIndex], sortOrder);
}
使用它来调用以上功能:
List<int> selectedIndices;
ListSortDirection sortOrder;
int? sortColumnIndex;
DataGridView dgv;
dgv.GetDataGridViewUIInfo(out selectedIndices, out sortColumnIndex, out sortOrder);
// Refresh the data source of the data gridview
dgv.SetDataGridViewUIInfo(selectedIndices, sortColumnIndex, sortOrder);