本篇我們來介紹Windows Phone 8.1 新特性中的列表選擇控件。
在Windows Phone 8 時代,大家都會使用 LongListSelector 來實現列表選擇控件,對數據進行分組顯示。比如通訊錄中,按照名字首字母進行分組,點擊分組標題后跳轉到該標題對應的分組。
而Windows Phone 8.1 中會利用 ListView 和 SemanticZoom 來實現,下面我們來看看實現過程。
首先我們來認識一下ListView 和 SemanticZoom:
ListView 從字面上並不難理解,一個列表視圖控件,而它實際的作用也和字面表現的差不多,它是一個在一個列表中滾動顯示項目的集合控件。
SemanticZoom 可能看起來有些陌生,語義縮放。它是允許用戶在集合項目的兩個視圖之間縮放的一個容器控件。簡單來說,當我們對一個聯系人集合進行了按首字母分組后,我們可以通過語義縮放控件完成聯系人列表和字母列表兩種視圖的縮放,通過選擇字母來導航到該字母分組。
下面我們來看看代碼實現,首先是XAML:
<SemanticZoom x:Name="semanticZoom" IsZoomOutButtonEnabled="True" CanChangeViews="True"> <SemanticZoom.ZoomedInView> <ListView x:Name="listViewDetail" IsSwipeEnabled="True" IsTapEnabled="True" IsItemClickEnabled="True" IsZoomedInView="True"> <ListView.ItemTemplate> <DataTemplate> <Grid Height="40"> <Grid.ColumnDefinitions> <ColumnDefinition Width="50"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Border Background="AliceBlue" Grid.Column="0"/> <TextBlock Grid.Column="1" Text="{Binding ContactName}" FontSize="30"/> </Grid> </DataTemplate> </ListView.ItemTemplate> <ListView.GroupStyle> <GroupStyle> <GroupStyle.HeaderTemplate> <DataTemplate> <Border Background="Blue" Height="50" Width="50" HorizontalAlignment="Left" Margin="0,20,0,20" Tapped="Border_Tapped"> <TextBlock Text="{Binding Title}" FontSize="30"/> </Border> </DataTemplate> </GroupStyle.HeaderTemplate> <GroupStyle.Panel> <ItemsPanelTemplate> <VariableSizedWrapGrid Orientation="Vertical" Margin="0 0 0 20" ItemHeight="75"/> </ItemsPanelTemplate> </GroupStyle.Panel> </GroupStyle> </ListView.GroupStyle> <ListView.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Vertical" /> </ItemsPanelTemplate> </ListView.ItemsPanel> </ListView> </SemanticZoom.ZoomedInView> <SemanticZoom.ZoomedOutView> <ListView x:Name="listViewSummary" Background="Black" IsZoomedInView="False"> <ListView.ItemTemplate> <DataTemplate> <Border Height="70" Width="400" Background="Blue" Margin="10,10,10,10"> <TextBlock Text="{Binding Group.Title}" FontSize="30"/> </Border> </DataTemplate> </ListView.ItemTemplate> <ListView.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Vertical"/> </ItemsPanelTemplate> </ListView.ItemsPanel> </ListView> </SemanticZoom.ZoomedOutView> </SemanticZoom>
代碼中我們為SemanticZoom 定義了兩種視圖,ZoomedInView 和 ZoomedOutView,分別代表元素列表視圖和概要(分組名)視圖。為這兩種視圖分別定義了內容,即 ListView。ZoomedInView 中我們定義了一個聯系人列表,每個元素包括了一個Border 和一個代表人名的文本控件,這些元素按照首字母分組,點擊首字母時進入ZoomedOutView。ZoomedOutView 是一個字母列表,選擇某個字母后,列表回到ZoomedInView,且導航到該字母的分組。
下面我們看看數據的綁定過程:
protected override void OnNavigatedTo(NavigationEventArgs e) { CollectionViewSource listViewSource = new CollectionViewSource(); listViewSource.IsSourceGrouped = true; listViewSource.Source = GetContactGroups(); listViewSource.ItemsPath = new PropertyPath("Contacts"); listViewDetail.ItemsSource = listViewSource.View; listViewSummary.ItemsSource = listViewSource.View.CollectionGroups; } private List<ContactGroup> GetContactGroups() { List<ContactGroup> groups = new List<ContactGroup>(); ContactGroup groupA = new ContactGroup() { Title = "A", Contacts = new List<Contact>() { new Contact("Alan"), new Contact("Allen"), new Contact("Azar") } }; ContactGroup groupB = new ContactGroup() { Title = "B", Contacts = new List<Contact>() { new Contact("Ben"), new Contact("Benzema") } }; ContactGroup groupC = new ContactGroup() { Title = "C", Contacts = new List<Contact>() { new Contact("Cat"), new Contact("Canby"), new Contact("Candy") } }; ContactGroup groupJ = new ContactGroup() { Title = "J", Contacts = new List<Contact>() { new Contact("James"), new Contact("Jim"), new Contact("Jimmy") } }; ContactGroup groupK = new ContactGroup() { Title = "K", Contacts = new List<Contact>() { new Contact("Kevin"), new Contact("King") } }; ContactGroup groupO = new ContactGroup() { Title = "O", Contacts = new List<Contact>() { new Contact("Oscar"), new Contact("Owen") } }; ContactGroup groupP = new ContactGroup() { Title = "P", Contacts = new List<Contact>() { new Contact("Pendy") } }; ContactGroup groupY = new ContactGroup() { Title = "Y", Contacts = new List<Contact>() { new Contact("Yark"), new Contact("York")} }; ContactGroup groupZ = new ContactGroup() { Title = "Z", Contacts = new List<Contact>() { new Contact("Zend"), new Contact("Zin")} }; groups.Add(groupA); groups.Add(groupB); groups.Add(groupC); groups.Add(groupJ); groups.Add(groupK); groups.Add(groupO); groups.Add(groupP); groups.Add(groupY); groups.Add(groupZ); return groups; } private void Border_Tapped(object sender, TappedRoutedEventArgs e) { semanticZoom.IsZoomedInViewActive = false; }
public class Contact { public string ContactName { get; set; } public Contact(string name) { ContactName = name; } } public class ContactGroup { public string Title { get; set; } public List<Contact> Contacts { get; set; } }
這里我們演示了數據結構的定義,示例數據的生成和綁定。我們重點來看一下數據綁定的過程,這個過程在 OnNavigatedTo 方法中。
我們定義了一個 CollectionViewSource 類型的實例,它可以向集合類添加分組支持的數據源。把它的Source設置為我們定義的數據分組集合。
ItemsPath 代表在組內查找組的屬性路徑。然后把listViewDetail 和 listViewSummary 的數據源分別設置為 CollectionViewSource 的視圖對象和視圖的集合組。
這樣我們的示例就完成了,來看一下運行效果:
上圖1 中,我們點擊某個分組名后,出現圖2 的視圖,在圖2 中點擊“K” 后,回到列表視圖,且導航到“K”分組。
到了,到這里我們對列表選擇控件的介紹就完成了,接下來會繼續介紹Windows Phone 8.1中的其他新控件,謝謝大家。