Xaml 在UWP中缓慢调整GridView大小

Xaml 在UWP中缓慢调整GridView大小,xaml,gridview,windows-10,win-universal-app,Xaml,Gridview,Windows 10,Win Universal App,为了简化示例,假设我们只在页面中添加一个GridView: 这是代码: public主页() { this.InitializeComponent(); this.Loaded+=主页面_Loaded; } 已加载专用异步void主页(对象发送方、路由目标) { var collection=新的ObservableCollection(); MainGrid.ItemsSource=集合; 等待Dispatcher.RunIdleAsync(测试=> { 对于(int i=0;i

为了简化示例,假设我们只在页面中添加一个GridView:


这是代码:

public主页()
{
this.InitializeComponent();
this.Loaded+=主页面_Loaded;
}
已加载专用异步void主页(对象发送方、路由目标)
{
var collection=新的ObservableCollection();
MainGrid.ItemsSource=集合;
等待Dispatcher.RunIdleAsync(测试=>
{
对于(int i=0;i<20000;i++)
{
collection.Add(i.ToString());
}
});
}
GridView中充满了可观察的集合,我并不抱怨滚动,而是抱怨窗口的大小和最大化会造成巨大的延迟,在低规格的计算机中甚至更糟

我已经做了以下改进:

  • 使用IncrementalLoadingThreshold和DataFetchSize的值
  • 
    
    有时效果更好,但不确定此值是否适用于静态集合

  • 将对齐方式更改为“上”和“左”,以跟踪尺寸更改并适应栅格
  • 这会更好,但当我点击maximize时,它有一个很大的滞后

    我也尝试过像这样的老例子,但当滚动到最后时,它不会添加更多的项目。我找到的性能提示和文章都是用于滚动的


    因此,在这种静态情况下,是否有一种技术或另一个收集源来改善调整滞后?

    首先创建一个新的可观察收集,允许您添加范围。这是我的

    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));
        }
    }
    
    公共类ObservableCollection 2:ObservableCollection
    {
    bool\u suppressNotification=false;
    CollectionChanged上的受保护覆盖无效(NotifyCollectionChangedEventArgs e)
    {
    如果(!\u禁止通知)
    基础。变更的集合(e);
    //无所事事
    }
    公共ObservableCollection2():base(){}
    公共ObservableCollection2(IEnumerable集合):基础(集合)
    { }
    public void AddRange(IEnumerable列表)
    {
    这是。_suppressNotification=true;
    if(list==null)
    抛出新的ArgumentNullException(“列表”);
    int index=this.Count;
    foreach(列表中的T项)
    {
    基础.项目.添加(项目);
    }
    这是。_suppressNotification=false;
    OnPropertyChanged(新系统.ComponentModel.PropertyChangedEventArgs(“计数”);
    OnPropertyChanged(新的System.ComponentModel.PropertyChangedEventArgs(“项[]”);
    OnCollectionChanged(新的NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add,list.ToList(),index));
    }
    }
    
    接下来,您不会在加载时实例化集合,而是在构造函数中进行实例化

    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);
    
    }
    
    public主页()
    {
    this.InitializeComponent();
    dataCol=新的ObservableCollection2();
    }
    ObservableCollection2数据列=null;
    受保护的覆盖异步无效OnNavigatedTo(NavigationEventArgs e)
    {
    MainGrid.ItemsSource=数据列;
    列表模板列表=新建列表();
    对于(int i=0;i<20000;i++)
    {
    添加(i.ToString());
    }
    dataCol.AddRange(tempList);
    }
    

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

    两个方面的说明:不需要在调度程序的最后一行上运行—从
    等待任务返回后…
    它已经在捕获的UI上下文上运行了。第二,不要在非UI线程中修改ObservableCollection(与UI控件一起使用)-您会遇到异常-您的案例有效,因为集合在填充后被设置为UI元素的itemssource,如果您交换订单,它将不起作用。但正如我所提到的,这些都是与你的问题无关的旁注。我开始从测试中删除代码,我已经更新了代码,我认为现在更干净了,多亏了这一点,还有其他可以更好工作的集合吗?ObservableCollection似乎是一个很好的集合-它的设计是在这种情况下使用UI元素。我不知道如何让它更好地工作,我会尝试使用GridView(ListView)的增量加载搜索一些内容-不需要时不要加载所有项目-可能尝试搜索有关ListView和增量加载的内容,方法LoadMoreItemsAsync等等。虽然我不确定这在您的情况下如何工作。可能是我没有很好地解释,我想解决的问题是,在您调整窗口大小后,控件会花费大量时间刷新自身。装载不是问题。无论如何,我认为对于GridView布局中的滞后问题,你无能为力。。你可以看看像Telerik这样的第三方控件。。我已经开始使用RadDataBoundListBox,因为stock控件不提供特定功能