2011-05-29 74 views
6

我有很多存儲在獨立存儲中的圖像,並希望將它們顯示在列表框中。但是,我不希望所有圖像都會立即加載,而是懶洋洋地加載。因此,只有當用戶滾動查看新項目時,圖像纔會被加載。我也想用數據綁定來提供列表項的數據和圖像。從隔離存儲中緩存加載列表框圖像

在測試中,我做的所有圖片總是立即加載,所以我不確定是否可以使用默認的ListBox和數據綁定來實現這種延遲加載。它可以?

+0

你可以查看這個博客和channel9視頻討論相同。源代碼也可用。 http://channel9.msdn.com/Shows/SilverlightTV/Silverlight-TV-72-Windows-Phone-Tips-for-Loading-Images http://jobijoy.blogspot.com/2011/05/wp7dev-tip-2 -few-things-to-remember-on.html – 2011-05-30 10:12:01

回答

7

你可以使用標準的ListBox來用數據綁定「延遲加載」你的項目。這裏的關鍵字是「數據虛擬化」。你必須實施IList到你想要綁定的類。索引器方法僅針對當前可見的項目和下一個計算的〜2個畫面。這也是您應該爲物品佈局使用固定尺寸網格的原因,而不是基於所有包含物品(性能!)的計算高度的堆疊面板。

您不必實現所有IList成員,只有幾個。這裏有一個例子:

public class MyVirtualList : IList { 
    private List<string> tmpList; 

    public MyVirtualList(List<string> mydata) { 
     tmpList = new List<string>(); 
     if (mydata == null || mydata.Count <= 0) return; 
     foreach (var item in mydata) 
      tmpList.Add(item); 
    } 

    public int Count { 
     get { return tmpList != null ? tmpList.Count : 0; } 
    } 

    public object this[int index] { 
     get { 
      Debug.WriteLine("Just requested item #" + index); 
      return tmpList[index]; 
     } 
     set { 
      throw new NotImplementedException(); 
     } 
    } 

    public int IndexOf(object value) { 
     return tmpList.IndexOf(value as string); 
    } 

    public int Add(object value) { 
     tmpList.Add(value as string); 
     return Count - 1; 
    } 

    #region not implemented methods 
    public void Clear() { 
     throw new NotImplementedException(); 
    } 

    public bool Contains(object value) { 
     throw new NotImplementedException(); 
    } 

    public void Insert(int index, object value) { 
     throw new NotImplementedException(); 
    } 

    public bool IsFixedSize { 
     get { throw new NotImplementedException(); } 
    } 

    public bool IsReadOnly { 
     get { throw new NotImplementedException(); } 
    } 

    public void Remove(object value) { 
     throw new NotImplementedException(); 
    } 

    public void RemoveAt(int index) { 
     throw new NotImplementedException(); 
    } 

    public void CopyTo(Array array, int index) { 
     throw new NotImplementedException(); 
    } 

    public bool IsSynchronized { 
     get { throw new NotImplementedException(); } 
    } 

    public object SyncRoot { 
     get { throw new NotImplementedException(); } 
    } 

    public IEnumerator GetEnumerator() { 
     throw new NotImplementedException(); 
    } 
    #endregion 
} 

在調試就可以看到,並不是所有的項目都在加載一次,但僅在需要時(見的Debug.WriteLine())。

+2

這很好,謝謝!完美的作品。關鍵字真的是「數據虛擬化」 - 用Google搜索將我帶到Shawn Oster的頁面,他也詳細闡述了該主題:http://shawnoster.com/blog/post/Improving-ListBox-Performance-in-Silverlight- for-Windows-Phone-7-Data-Virtualization.aspx – 2011-05-31 19:22:48

+0

只是爲了記錄:我沒有綁定到IList,我首先綁定到List。用IList替換這個List似乎在做伎倆。 – 2011-05-31 19:31:32

+0

我知道這是永遠以前,但使用可觀察的集合做同樣的事情是嗎? – Nico 2012-04-28 23:06:58

1

檢查this LazyListBox實現。該列表框將爲屏幕上可見的項目加載複雜的模板。對於屏幕上不可見的項目,您可以設置簡單模板。

+0

感謝您的鏈接,這是非常有趣的閱讀。目前Anheledir的解決方案對我來說已經足夠了。但是爲了將來我會密切關注LazyListBox。 – 2011-05-31 19:23:53