標籤:style class blog c code java
說到 List 控制項,Windows Phone 8.1 上推薦使用的是 ListView 和 GridView。
而這兩個控制項實在太多東西可講了,於是分成三篇來講:
(1)基本
(2)分組資料
(3)多資料呈現
ListView 和 GridView 的最大差別就是:ListView 是一條條依序排列的,而 GridView 則是一塊塊依序排列的,因此 ListView 中的一項就會佔據整整一行或者一列,而 GridView 的一項只會佔據它應有的大小,一行或一列中可以放置多項。
而兩者在其它方面上基本一致,因此下文只對 ListView 進行介紹,GridView 其實也一樣的。
多資料呈現,也就是說大量的資料要在 ListView 中呈現時,載入必定會較慢,那要如何讓使用者體驗更好呢?
(1)添加 ListView 的 ContainerContentChanging 事件
如字面意思所示,也就是當 ListView 的內容(也就是Item)發生改變時會觸發的事件:
<ListView ContainerContentChanging="IncrementalUpdateHandler"/>
(2)確定 Item 內容的呈現順序
比如 Item 的結構為:
Grid |__Border name=templatePlaceholder |__Image name=templateImage |__Grid |__TextBlock name=templateTitle |__TextBlock name=templateSubTitle
一般的做法都是先讓預留位置(templatePlaceholder)呈現,然後根據每項內容的重要程度和載入難度依次排序呈現。
假設這個 Item 的呈現順序為:Placeholder -> Title -> Image, SubTitle。
(3)處理 ListView 的 ContainerContentChanging 事件
private void IncrementalUpdateHandler(ListViewBase sender, ContainerContentChangingEventArgs args){ args.Handled = true;if( args.Phase != 0 ) throw new Exception("something went terribly wrong"); else { Grid templateRoot = (Grid)args.ItemContainer.ContentTemplateRoot; Border placeholder = (Border)templateRoot.FindName("templatePlaceholder"); Image itemImage = (Image)templateRoot.FindName("templateImage"); TextBlock title = (TextBlock)templateRoot.FindName("templateTitle"); TextBlock subtitle = (TextBlock)templateRoot.FindName("templateSubTitle"); placeholder.Opacity = 1; itemImage.Opacity = 0; title.Opacity = 0; subtitle.Opacity = 0; args.RegisterUpdateCallback(ShowText); }}
首先將 args.Handled 設為 true 以及檢查 args.Phase 是否不為 0。
然後根據控制項名稱找到各控制項,並根據需要設定每個控制項的 Opacity,隱藏或顯示它們。(注意,不能調整 Visible 屬性,因為這會再次觸發 ContainerContentChanging 事件)
最後調用 args.RegisterUpdateCallback(MethodName),顯示下一個要呈現的控制項內容。
private void ShowText(ListViewBase sender, ContainerContentChangingEventArgs args){ args.Handled = true; if( args.Phase != 1 ) throw new Exception("something went terribly wrong"); else { SampleItem sItem = (SampleItem)args.Item; Grid templateRoot = (Grid)args.ItemContainer.ContentTemplateRoot; TextBlock title = (TextBlock)templateRoot.FindName("templateTitle"); title.Text = sItem.Title; title.Opacity = 1; args.RegisterUpdateCallback(ShowImage); }}
ShowText
private void ShowImage(ListViewBase sender, ContainerContentChangingEventArgs args){ args.Handled = true; if( args.Phase != 2 ) throw new Exception("something went terribly wrong"); else { SampleItem sItem = (SampleItem)args.Item; Grid templateRoot = (Grid)args.ItemContainer.ContentTemplateRoot; Image itemImage = (Image)templateRoot.FindName("templateImage"); TextBlock subtitle = (TextBlock)templateRoot.FindName("templateSubTitle"); Border placeholder = (Border)templateRoot.FindName("templatePlaceholder"); itemImage.Source = new BitmapImage(new Uri(sItem.ItemImage)); subtitle.Text = sItem.TargetGroup; itemImage.Opacity = 1; subtitle.Opacity = 1; placeholder.Opacity = 0; }}
ShowImage
其實也就是根據第二步中確定的內容呈現順序依次調用 RegisterUpdateCallback。