在GUI更新期间如何防止WPF窗口冻结?

时间:2012-12-18 16:55:56

标签: wpf wpfdatagrid inotifypropertychanged freeze bindinglist

我有一个包含1000行的数据网格。 ItemsSource是一个CollectionViewSource。我的CollectionViewSource的源代码是一个包含我称之为RowTypes的对象的BindingList。我的RowType对象实现了INotifyPropertyChanged。每个RowType的一个属性大约每两秒更改一次。这意味着我的数据网格的一列中的值每两秒更改一次。

我的问题是此更新会影响用户体验。此更新大约需要一秒钟,在此期间用户无法对GUI执行任何操作。如果在用户滚动数据网格的记录时发生此更新,则滚动将停止(冻结),然后在一秒钟后向前跳转。这令人分心。

在更新执行此更新时,有没有办法防止窗口冻结?

3 个答案:

答案 0 :(得分:2)

只需在单独的线程(不是UI线程)中执行读取操作。 WPF将完美地改变视图上的标量属性。您可以轻松开始新任务:

System.Threading.Tasks.Task.Factory.StartNew(() =>
{
    try
    {
        // This method is heavy call - to the DataBase or to the WebService
        ReadData(); 
        // In this method, do the updates of the properties of 
        // your RowType collection. You can do it in previous method.
        UpdateData();
     }
    catch (Exception e)
    {
        // you can log the errors which occurs during data updating
        LogError(e); 
    }
});

答案 1 :(得分:0)

确保DataGrid已启用虚拟化。有了它,它应该只实际更新屏幕上显示的内容,而不是所有1000行。这应该不会花费一整秒,除非你在那里有一个疯狂的行数我想。

答案 2 :(得分:0)

您是否尝试过DeferRefresh()

var view = CollectionViewSource.GetDefaultView(RowTypesList);
using (view.DeferRefresh())
{
    // perform updates here
}