简体   繁体   中英

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. If I try to update in the current setup the UI freezes completely when I'm adding the new rows to the ObservableCollection. To work around this I set the CollectionViewSource.Source = null before adding the rows to the ObservableCollection which allows it to work fine. The only problem is that once I do this for the first load the next load will still have the UI freezing problem. 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.

//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:

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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