Xaml 在UWP中缓慢调整GridView大小
为了简化示例,假设我们只在页面中添加一个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
这是代码:
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中充满了可观察的集合,我并不抱怨滚动,而是抱怨窗口的大小和最大化会造成巨大的延迟,在低规格的计算机中甚至更糟
我已经做了以下改进:
有时效果更好,但不确定此值是否适用于静态集合
因此,在这种静态情况下,是否有一种技术或另一个收集源来改善调整滞后?首先创建一个新的可观察收集,允许您添加范围。这是我的
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控件不提供特定功能