C# - 数据网格视图更新

本文关键字:视图 更新 网格 数据网 数据 | 更新日期: 2023-09-27 18:34:55

我的应用程序需要定期使用数据库中的数据自动更新datagridview,以反映系统中的更改,这不是问题。

我的问题是,当数据网格视图更新时,它会短暂冻结 UI 并阻止滚动。所以我可以想到两种可能的解决方案:

在 UI 事件处于活动状态时暂停更新 - 尽管我不知道全局用户事件是什么?

或者使用后台工作线程来更新数据网格视图 - 尽管我不知道您将如何从后台工作线程更新 UI?

using (SqlDataAdapter a = new SqlDataAdapter("SELECT Name,Value FROM dbo.IOData", c))
{
  DataTable IOProcData = new DataTable();
  // Populate data table
  a.Fill(IOProcData);
  // Record displayed row
  int temp = dataGridView1.FirstDisplayedScrollingRowIndex;
  IOBinding.DataSource = IOProcData;
  // Reset displayed row
  if (temp > 0)
  {
    dataGridView1.FirstDisplayedScrollingRowIndex = temp;
  }
}

编辑:

当第一次像鼠标按下一样单击数据网格视图的滚动条但针对滚动条时,是否有触发的事件?滚动事件发生在滚动操作之后,因此会延迟。

C# - 数据网格视图更新

您可以分离责任。耗时的过程可能是从数据库获取数据,而不是分配数据源。

在后台工作线程中,您可以从数据库中获取信息。完成后,只需将填充的表分配给网格视图即可。

下面是一个示例:

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
        if (e.Error != null) {
            //Handle error
        } else {
            IOBinding.DataSource = (DataTable)e.Result;
        }
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) {
    using (SqlDataAdapter a = new SqlDataAdapter("SELECT Name,Value FROM dbo.IOData", c)) {
        DataTable IOProcData = new DataTable();
        // Populate data table
        a.Fill(IOProcData);
        // Record displayed row
        e.Result = a;
    }
}

您可以初始化一个负责获取新数据并更新 DataGrid 的计时器线程

internal void InitTimer()
    {
        _timer = new Timer();
        _timer.Tick += (sender, args) => BindDataGrid();
        _timer.Interval = 1000;
        _timer.Start();
        _timerStart = true;
    }

关于滚动问题,在更新所选行变为 0 后,我遇到了另一个问题。我通过将 DataTable 绑定到 DataGrid 并将两个结果合并在一起来解决这个问题。

  var newData = // your data as DataTable Format;
  // Get Current Scroll position
  var scrollingRowIndex = MyDataGridView.FirstDisplayedScrollingRowIndex;
  // Get Current Row
  var currentRow = MyDataGridView.CurrentCell != null
                                 ? MyDataGridView.CurrentCell.RowIndex
                                 : -1;
  DataTable bindedData;
  var currentDataSource = MyDataGridView.DataSource as DataTable;

  if (currentDataSource != null)
  {
       currentDataSource.Merge(newData);
       bindedData = currentDataSource;
  }
  else
  {
      bindedData = newData;
  }
  MyDataGridView.DataSource = bindedData;
  MyDataGridView.Update();
  // set Current Scroll position
  if (scrollingRowIndex > -1)
         MyDataGridView.FirstDisplayedScrollingRowIndex = scrollingRowIndex;
  // set Current Row
  if (currentRow > -1)
         MyDataGridView.Rows[currentRow].Selected = true;