刷新DataGrid而不冻结应用程序(异步)

时间:2015-01-11 21:24:14

标签: c# wpf asynchronous datagrid refresh

我有一个填充了'可验证对象'的DataGrid。验证一个对象大约需要150ms。

一行如下:

enter image description here

如果我验证一个对象,它可能有效或无效:

enter image description here

enter image description here

我可以验证DataGrid中的所有对象。 目前我在验证所有对象后刷新了datagrid gui(数据网格在禁用验证期间)。但是如果数据网格中填充了数千个对象,则可能需要几分钟,但用户应该看到进度。我的想法:每次验证后刷新数据网格。但刷新需要很长时间(如100-300ms)...如果我的数据网格中有500个对象,则必须刷新500次,并且在刷新期间应用程序GUI冻结...基本上gui在验证期间永久冻结

有没有办法只刷新一行?或者:是否可以刷新datagrid异步? 我不关心数据网格是否冻结(无论如何都被禁用),但应用程序不应该冻结。

编辑:我正在使用DataBinding到ObservableCollection。每次验证后,我都会触发PropertyChanged事件(INotifyPropertyChanged)。虽然每次验证后都没有更新......

2 个答案:

答案 0 :(得分:0)

这是一项棘手的业务,因为您无法异步刷新网格,因为这意味着您将在单独的线程上执行此操作,并且应该更新UI的唯一线程是UI线程。

但是,如果您的数据源与网格相关联,则可以使用System.ComponentModel.BindingList作为数据源。然后,您可以在单独的线程上更新绑定列表,这将导致仅更新的行或单元受到影响。这是一个例子。

这是一个类级声明/赋值:

Private myList As New System.ComponentModel.BindingList(Of String)(New List(Of String)({"First", "Second", "Third"}))

这是表单加载事件处理程序:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    DataGridView1.DataSource = myList
End Sub

然后你可以在你的主要代码的任何方法内执行此操作。我正在使用按钮点击事件处理程序:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    myList.RaiseListChangedEvents = False

    Task.Factory.StartNew(Sub()
                              Me.Invoke(Sub() myList.Add("Fourth"))
                          End Sub)

    myList.RaiseListChangedEvents = True
    myList.ResetBindings()
End Sub

答案 1 :(得分:0)

您能告诉我们一些关于如何填充DataGrid的代码吗?

通常,您不想刷新整个列表。相反,您应该使用数据绑定和属性更改通知来刷新/更新已更改的值。

这可以通过将有效性列绑定到数据对象的有效性属性(希望实现INotifyPropertyChanged),然后在完成验证检查后更新此属性来实现。如果没有看到某些代码,很难更具体。