LongListSelector是一個增強版的列表控件,它能夠實現分組的列表,如系統人脈列表的交互效果就能夠利用LongListSelector控件去實現,同時LongListSelector也同樣能夠實現和ListBox同樣的列表效果。在使用LongListSelector控件的時候能夠使用IsGroupingEnabled屬性來控制你要實現的是分組的效果,仍是非分組的列表效果。async
下面咱們用LongListSelector來實現一個非分組的列表效果,同時還要實現的功能是列表下拉自動刷新的效果。LongListSelector實現非分組列表效果和ListBox控件是相似的,經過對ItemTemplate模板進行設置,而後綁定集合的相關屬性就能夠了。在前面的章節由介紹過一個使用ListBox控件判斷列表滾動到底的例子,實現的原理是經過可視化樹獲取ListBox的ScrollViewer控件,而後根據ScrollViewer控件的垂直位移屬性來判斷ListBox控件何時滾動到底。可是LongListSelector內部沒有采用ScrollViewer控件,因此咱們不能採用這種方式來實現下拉自動刷新的功能。那麼咱們這個例子是經過LongListSelector控件的ItemRealized事件去控制自動刷新的邏輯,由於LongListSelector控件是對數據進行虛擬化處理的,當列表向下滾動的時候下面的數據就會不斷地被實例化,當數據實例化的時候就會觸發ItemRealized事件,因此我只須要監控到當列表最後一個數據實例化的時候就能夠出發數據刷新的邏輯就能夠了。代碼以下所示:函數
<phone:LongListSelector x:Name="lls" ItemsSource="{Binding Items}" IsGroupingEnabled="False"> <phone:LongListSelector.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding FirstName}" FontSize="30"></TextBlock> <TextBlock Text="{Binding LastName}" FontSize="30" Margin="30,0,0,0"></TextBlock> </StackPanel> </DataTemplate> </phone:LongListSelector.ItemTemplate> </phone:LongListSelector>
public partial class MainPage : PhoneApplicationPage { // 綁定的數據集合 public ObservableCollection<Item> Items { get; set; } // 數據加載的標識 public bool IsLoading = false; // 線程鎖的對象 private object o = new object(); // 構造函數 public MainPage() { InitializeComponent(); // 列表初始化加載100個數據項 Items = new ObservableCollection<Item>(); for (int i = 0; i < 100; i++) { Items.Add(new Item { FirstName = "Li" + i, LastName = "Lei" + i }); } this.DataContext = this; } // 頁面加載完成,訂閱列表的ItemRealized事件 private void PhoneApplicationPage_Loaded_1(object sender, RoutedEventArgs e) { lls.ItemRealized += lls_ItemRealized; } // ItemRealized事件處理程序,在這裏判斷刷新的時機 void lls_ItemRealized(object sender, ItemRealizationEventArgs e) { // 由於該事件會被多個線程進入,因此添加線程鎖,控制下面的代碼只能單個線程去執行 lock (o) { if (!IsLoading) { if (e.ItemKind == LongListSelectorItemKind.Item) { if ((e.Container.Content as Item).Equals(lls.ItemsSource[lls.ItemsSource.Count - 1])) { // 設置IsLoading爲true,在加載數據的過程當中,禁止屢次進入 IsLoading = true; // 顯示系統托盤的進度條 Microsoft.Phone.Shell.ProgressIndicator progressIndicator = new Microsoft.Phone.Shell.ProgressIndicator(); Microsoft.Phone.Shell.SystemTray.ProgressIndicator = progressIndicator; progressIndicator.Text = "加載中..."; progressIndicator.IsIndeterminate = true; progressIndicator.IsVisible = true; // 模擬後臺耗時任務拉取數據的場景 Task.Factory.StartNew(async () => { await Task.Delay(3000); // 調用UI線程添加數據 this.Dispatcher.BeginInvoke(() => { int count = Items.Count; for (int i = count; i < count + 50; i++) { Items.Add(new Item { FirstName = "Li" + i, LastName = "Lei" + i }); } // 關閉進度條 progressIndicator.IsVisible = false; // 修改加載的狀態 IsLoading = false; }); }); } } } } } }