简体   繁体   English

更改ObservableCollection / CollectionViewSource时UI冻结

[英]UI freezing when altering ObservableCollection/CollectionViewSource

I have a datagrid that is receiving an update of 100,000+ rows which is bound to a CollectionViewSource.View whose source is an ObservableCollection. 我有一个数据网格正在接收100,000+行的更新,该行绑定到源为ObservableCollection的CollectionViewSource.View。 If I try to update in the current setup the UI freezes completely when I'm adding the new rows to the ObservableCollection. 如果我尝试在当前设置中进行更新,则在将新行添加到ObservableCollection时,UI会完全冻结。 To work around this I set the CollectionViewSource.Source = null before adding the rows to the ObservableCollection which allows it to work fine. 要解决此问题,我在将行添加到ObservableCollection之前将CollectionViewSource.Source = null设置为允许其正常工作。 The only problem is that once I do this for the first load the next load will still have the UI freezing problem. 唯一的问题是,一旦我对第一个加载执行此操作,则下一个加载仍将存在UI冻结问题。 Here's the code. 这是代码。

public CollectionViewSource ViewSource { get; set; }
private ObservableCollection<ScreenerRow> internalRows = new ObservableCollection<ScreenerRow>();


private async Task Search()
{
    internalRows.Clear();
    ViewSource.Source = null;
    var data = await Task.Run(() =>
    {
        return DoStuff();
    });
    if (data == null) return;
    foreach (ScreenerRow sRow in data)
    {
        //freezes in here on second run
        internalRows.Add(sRow);
    }
    ViewSource.Source = internalRows;
}

Just wondering if anyone else has had this problem or see's an issue with the way I am doing this. 只是想知道是否有人遇到过这个问题,或者我的操作方式是否有问题。 Thanks for the help. 谢谢您的帮助。

Edit: Changing my ObservableCollection to a List allows this to work fine. 编辑:将我的ObservableCollection更改为列表,可以使其正常工作。

//private ObservableCollection<ScreenerRow> internalRows = new ObservableCollection<ScreenerRow>();
private List<ScreenerRow> internalRows = new List<ScreenerRow>();

I take it from your edit that this may not be the case, but if there are cases where you actually need the collection to be observable, then you can also use the CollectionViewSource.DeferRefresh() method to prevent the UI from being updated after each individual change: 我从您的编辑中得出可能不是这种情况,但是如果确实需要实际观察集合,则还可以使用CollectionViewSource.DeferRefresh()方法来防止每次更新UI后个人变更:

private async Task Search()
{
    internalRows.Clear();
    using(ViewSource.DeferRefresh())
    {
        var data = await Task.Run(() => GetSearchResults());

        if (data == null) return;

        foreach (ScreenerRow sRow in data)
        {                
            internalRows.Add(sRow);
        }           
    }
}

And also make sure that you have the virtualization mode set correctly on the control. 还要确保在控件上正确设置了虚拟化模式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM