本篇我們來介紹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中的其他新控件,謝謝大家。