2015-06-25 118 views
0

我正在使用Windows 10通用應用程序,並在我的應用程序中使用ListView時看到一些閃爍的問題。我的ListView使用x:Bind綁定到View Model中的ObservableCollection。更新綁定集合時ListView閃爍

當用戶執行某些操作或發生後臺更新時,我會進行一些處理,需要刷新ObservableCollection。

private ObservableCollection<Item> UIItems = new ObservableCollection<Item>(); 
    private bool IsUpdating = false; 

    private void UpdateUIProperties(List<Item> newItems) 
    { 
     DispatcherHelper.CheckBeginInvokeOnUI(() => 
     { 
      IsUpdating = true; 
      UIItems.Clear(); 
      foreach (var item in newItems) 
      { 
       if (item.IsVisible) 
       { 
        UIItems.Add(item); 
       } 
      } 
      IsUpdating = false; 
     }); 
    } 

執行此代碼後,ListView閃爍,然後滾動查看器一路走到頂部。有什麼辦法來防止這種情況,並讓ListView的ScrollViewer停留在原來的偏移量?

回答

1

似乎對我有用的解決方案是將Itemsource綁定到Observable集合,然後再包含您要添加的項目的另一個集合。在集合中有Item實現下面的接口。當您想要更新集合時,請使用MergeCollection方法確保集合中的項目已保存,但它們具有新的配置。

public interface IConfigureFrom<T> 
    { 
     void ConfigureFrom(T other); 
    } 

    public static void MergeCollection<T>(ICollection<T> source, ICollection<T> dest) where T : IConfigureFrom<T>, new() 
    { 
     // First remove entries at the bottom of the dest list that are no longer there 
     if (dest.Count > source.Count) 
     { 
      for (int i = dest.Count - 1; i >= source.Count; i--) 
      { 
       var coll = dest as Collection<T>; 
       if (coll != null) 
       { 
        coll.RemoveAt(i); 
       } 
       else 
       { 
        dest.Remove(dest.Last()); 
       } 
      } 
     } 

     // reconfigure existing entries with the new configureation 
     var sourecList = source.ToList(); 
     var destList = dest.ToList(); 

     for (int i = dest.Count - 1; i >= 0; i--) 
     { 
      var target = destList[i]; 
      var config = sourecList[i]; 
      target.ConfigureFrom(config); 
     } 


     // add new entries at the end and configure them from the source list 
     for (int i = dest.Count; i < source.Count; i++) 
     { 
      T newItem = new T(); 
      newItem.ConfigureFrom(sourecList[i]); 
      dest.Add(newItem); 
     } 

    } 
0

更改ListView中的所有項目時,通常交換整個ItemsSource通常會更好。

只需設置:

UIItems = new List<...>(your data); 

並擁有這火當然OnNotifyPropertyChanged。

+0

這樣做的問題是它會導致ListView在UIItems集合更新後滾動到頂部。通過上述解決方案,滾動偏移量將保持不變。 –

+0

將ItemsUpdatingScrollMode設置爲KeepScrollOffset:請參見:http://stackoverflow.com/questions/27924000/prevent-the-listview-from-scrolling-to-its-top-position-when-itemsource-changed/27933274#27933274 –

+0

但說實話:無論如何,當刪除集合中的所有項目時,視圖是否應該保留?如果您只是更換*一些*項目,爲什麼不更新這些而不是重新填充集合? –