为了简化示例,我们假设我们只是在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会造成很大的延迟,甚至在低规格的计算机中也会更糟。
我做了以下改进:
<GridView x:Name="MainGrid" IncrementalLoadingThreshold="100" DataFetchSize="3"/>
有时会更好但不确定这些值是否适用于静态集合。
这样做会更好但是当我点击最大化时它会有很大的延迟。
我还尝试按照http://xurxodeveloper.blogspot.com.es/2014/03/scroll-infinito-en-windows-81-con-xaml.html等旧示例进行操作,但滚动到达结尾时它不会添加更多项目。我发现的性能提示和文章只是用于滚动。
所以在这种静态情况下,是否有技术或其他收集源来改善调整大小延迟?
答案 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次