优雅地刷新DataGridView中的数据

本文关键字:数据 DataGridView 刷新 | 更新日期: 2023-09-27 18:00:40

我在Windows窗体中有一个DataGridView,这个网格包含接近实时的数据——我希望它至少每20秒更新一次。我的网格绑定到我用程序生成的DataTable,所以我现在有一个计时器来生成这个DataTable,并每20秒将其分配给网格。

但我遇到的问题是,当数据刷新时,网格上的任何选择或排序都会消失,这是一个很大的可用性问题。有没有其他方法可以刷新网格的内容,保留选择/排序?

优雅地刷新DataGridView中的数据

恢复排序顺序和行选择的粗略指南。

在刷新之前执行此操作:

// 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);