window phone7中listbox,ItemsControl等项渲染速度慢的解决方案

背景:ui使用ScrollViewer+ItemsControl(Listbox是有这两个控件组合出来的),绑定到ItemsControl上的ItemSource的是一个ObservableCollection<T>,使用它是因为它实现了INotifyCollectionChanged, INotifyPropertyChanged接口,在其它地方修改这个ObservableCollection<T>集合,就会更新对应ui显示,我说的其它地方当然指的有codebehind里,还有使用的mvvm框架里的viewModel等,本人使用的是mvvm框架;在viewmodel里异步请求数据,获取完数据后添加到ObservableCollection<T>集合里就可以了,这种实现,功能上ok,可是伴随的问题来了,当viewModel初始化后发送异步请求,在添加到ObservableCollection<T>过程中,Ui并未逐条数据渲染显示,而是等一段时间后渲染显示,这个当数据量达到40-60条时,渲染特别慢,这当然是不能忍受的;

分析:初步分析是因为性能、集合太大等引起的,但是在调试这些之后并没能解决问题;找了好多方法,未能解决;后来看了msdn上的博客才知道具体解决办法,

大致原因是因为,我获取数据的请求时异步请求,在获取到数据后,异步add数据到到ObservableCollection<T>占用了主线程,一直等到将所有数据添加到ObservableCollection<T>后,主线程才回到ui线程将ObservableCollection<T>的Change更新显示到UI上;

解决办法: 了解这个之后,就可以找到解决办法了,就是在foreach将response里的数据添加到ObservableCollection<T>过程中,让单签线程暂停30毫秒,这时候逐次调用ui跨线程更新方法,在这个时间里,ui线程有足够资源去更新ui显示,最终效果就是listbox或ItemsControl在异步请求后,逐条将数据渲染显示,这样给用户的体验就好多了;

代码 :

 ObservableCollection<Friend> items =  new ObservableCollection<Friend>();
             int sleepcounter =  2;
             int itemcounter =  0;
             foreach (ItemViewModel item  in items)
            {
                itemcounter++;
                 if (itemcounter % sleepcounter ==  0)
                {
                    System.Threading.Thread.Sleep( 20);
                }
                 // add a dummy item
                 var myItem = item;

                 //  copy the data over
                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                     //  copy the list of bingimages over
                     this.items.Add(myItem);


                });
 }  


 
 

你可能感兴趣的:(listbox)