在频繁更新的网格中处理数据的最佳解决方案?

时间:2013-12-16 23:43:08

标签: c# winforms datagridview

我正在使用C#设计一个新的winform应用程序,但我无法找到特定部分的最佳解决方案。

应用程序的主要部分在网格中显示20行x 10列数据,它每秒从XML读取,它在后台线程中执行。

我遇到的问题是显示数据。我有一个每秒接收数据的DataSet,我将其设置为DataGridView的数据源,然后我将其更新以反映屏幕上的更改。

它非常快,我没有在屏幕上看到重新绘制,但是如果我点击并突出显示一个单元格,当更新触发时,我的单元格的焦点会跳回到左上角的单元格。

我能做些什么来阻止这种情况发生,同时每秒保持更新?

另外 - DatGridView是否是我需要的最佳控件,还是我应该考虑另一个控件(甚至构建自定义控件?)如果是这样 - 你会推荐什么?

1 个答案:

答案 0 :(得分:0)

您应该记住标识所选行的键值。然后在完成更新后,找到具有键值的行的索引;滚动到它,如果在更新后它不可见并选择单元格。

所以它看起来大概是这样的:

int colIndex = gridView.CurrentCell.ColumnIndex; //remember the selected column
var rowId = ...; // remember the Id of the selected row

//...update 

int rowIndex = ...; //find the index of the row by Id in the dataset
var rowToSelect = gridView.Rows[rowIndex]; //get the row in the grid by index
if (!rowToSelect.Displayed) //if this row is not visible on screen
    gridView.FirstDisplayedScrollingRowIndex = rowToSelect.Index; //scroll to it
gridView.CurrentCell = rowToSelect.Cells[colIndex]; //select the cell

另外请记住,如果您的网格使用排序,网格中的indeces可能与数据集中的indeces不同,那么您必须以不同方式搜索网格中的必要行。例如:

DataGridViewRow rowToSelect= gView.Rows
                     .OfType<DataGridViewRow>()
                     .FirstOrDefault(r => r.Cells[colIndex].Value.Equals(rowId));

此外,您可能会发现使用双缓冲有用。见SO: How to double buffer .NET controls on a form?。虽然我通常从gridView继承:

public class MyDataGridView : DataGridView
{
    public MyDataGridView()
    {
        DoubleBuffered = true;
    }
}