在UWP中慢速GridView调整大小

时间:2016-03-02 08:17:10

标签: xaml gridview windows-10 win-universal-app

为了简化示例,我们假设我们只是在Page:

中添加一个GridView
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <GridView x:Name="MainGrid" />
</Grid>

这是代码:

public MainPage()
{
    this.InitializeComponent();

    this.Loaded += MainPage_Loaded;
}

private async void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        var collection = new ObservableCollection<String>();

        MainGrid.ItemsSource = collection;

        await Dispatcher.RunIdleAsync(test =>
        {
            for (int i = 0; i < 20000; i++)
            {
                collection.Add(i.ToString());
            }
        });

    }

GridView充满了ObservableCollection,我不会抱怨滚动,但是关于调整大小和最大化Window会造成很大的延迟,甚至在低规格的计算机中也会更糟。

我做了以下改进:

  1. 使用IncrementalLoadingThreshold&amp;的值进行播放DataFetchSize
  2. <GridView x:Name="MainGrid" IncrementalLoadingThreshold="100" DataFetchSize="3"/>
    

    有时会更好但不确定这些值是否适用于静态集合。

    1. 将对齐方式更改为top和left以跟踪SizeChanged并适应Grid。
    2. 这样做会更好但是当我点击最大化时它会有很大的延迟。

      我还尝试按照http://xurxodeveloper.blogspot.com.es/2014/03/scroll-infinito-en-windows-81-con-xaml.html等旧示例进行操作,但滚动到达结尾时它不会添加更多项目。我发现的性能提示和文章只是用于滚动。

      所以在这种静态情况下,是否有技术或其他收集源来改善调整大小延迟?

1 个答案:

答案 0 :(得分:0)

首先创建一个允许AddRange的新Observable Collection。这就是我所拥有的

public class ObservableCollection2<T> : ObservableCollection<T>
{
    bool _suppressNotification = false;

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        if (!_suppressNotification)
            base.OnCollectionChanged(e);

        // do nothing
    }

    public ObservableCollection2() : base() { }
    public ObservableCollection2(IEnumerable<T> collection) : base(collection)
    { }

    public void AddRange(IEnumerable<T> list)
    {
        this._suppressNotification = true;

        if (list == null)
            throw new ArgumentNullException("list");

        int index = this.Count;

        foreach (T item in list)
        {
            base.Items.Add(item);
        }

        this._suppressNotification = false;

        OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs("Count"));
        OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs("Items[]"));
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, list.ToList(), index));
    }
}

接下来,您不要在Loaded上实例化集合,而是在构造函数中执行

public MainPage()
    {
        this.InitializeComponent();

        dataCol = new ObservableCollection2<String>();
    }

    ObservableCollection2<String> dataCol = null;

    protected override async void OnNavigatedTo(NavigationEventArgs e)
    {
    MainGrid.ItemsSource = dataCol;

    List<stirng> tempList = new List<string>();
    for (int i = 0; i < 20000; i++)
    {
        tempList .Add(i.ToString());
    }
    dataCol.AddRange(tempList);

}

简而言之,只有当集合处理完毕后,才会在每次插入后触发UI更新...这意味着GridView只获取一次更新通知而不是2000次