Windows Phone 8的列表控件天生支持分组,就像人脉应用中的类似,可以快速根据拼音首字母定位。在列表视图中点击分组标题后显示所有的组名,点击组名即可定位到这个组。我们自己开发的WP应用也能做到这样的分组功能,但需要一些额外的代码。下面的例子来自我的一个WP应用,有图有真相:
分组视图:
实现LongListSelector分组其实很简单。
1. 首先,你需要一个分组的助手类,这是一个相对标准的类,MSDN上抄来的:
public class Group<T> : List<T> { public Group(string name, IEnumerable<T> items) : base(items) { this.Title = name; } public string Title { get; set; } public static List<Group<T>> GetItemGroups<T>(IEnumerable<T> itemList, Func<T, string> getKeyFunc) { IEnumerable<Group<T>> groupList = from item in itemList group item by getKeyFunc(item) into g orderby g.Key select new Group<T>(g.Key, g); return groupList.ToList(); } }
然后,对于你要分组的内容,就能通过getKeyFunc委托来指定依据哪个字段分组了。比如我应用里的电影列表希望根据电影名称进行分组,即MovieInfo.Title,代码就要这样写:
this.GroupedQueryResults = Group<MovieInfo>.GetItemGroups(rawCollection, m => m.Title).ToObservableCollection();
其中,rawCollection是一个未经过分组的IEnumerable<MovieInfo>列表。
2. 在XAML页面里,LongListSelector所绑定的对象需要设置为经过分组的GroupedQueryResults。
<phone:LongListSelector ItemsSource="{Binding GroupedQueryResults, Mode=TwoWay}" LayoutMode="List" IsGroupingEnabled="True" HideEmptyGroups="True" JumpListStyle="{StaticResource MovieListJumpListStyle}" >
IsGroupingEnabled属性必须设置为true,以启用分组功能。
HideEmptyGroups属性为是否隐藏没有数据的组,true为不显示,false为显示。
JumpListStyle是分组视图的样式,我的应用里样式定义如下:
<Style x:Key="MovieListJumpListStyle" TargetType="phone:LongListSelector"> <!--<Setter Property="GridCellSize" Value="113,113"/>--> <Setter Property="LayoutMode" Value="List" /> <Setter Property="ItemTemplate"> <Setter.Value> <DataTemplate> <Border Background="{Binding Converter={StaticResource BackgroundConverter}}" Width="400" Height="90" Margin="6" > <TextBlock Text="{Binding Title}" FontFamily="{StaticResource PhoneFontFamilySemiBold}" FontSize="30" Padding="6" Foreground="{Binding Converter={StaticResource ForegroundConverter}}" VerticalAlignment="Center"/> </Border> </DataTemplate> </Setter.Value> </Setter> </Style>
最后,我们还需要指定列表视图中组标题的模板。我的模板如下:
<phone:LongListSelector.GroupHeaderTemplate> <DataTemplate> <Border Background="Transparent" Padding="5"> <Border Background="{StaticResource PhoneAccentBrush}" BorderBrush="{StaticResource PhoneAccentBrush}" BorderThickness="2" Height="62" Margin="0,20,0,5" HorizontalAlignment="Left"> <TextBlock Text="{Binding Title}" Foreground="{StaticResource PhoneForegroundBrush}" FontSize="36" Padding="6" FontFamily="{StaticResource PhoneFontFamilySemiLight}" HorizontalAlignment="Left" VerticalAlignment="Center"/> </Border> </Border> </DataTemplate> </phone:LongListSelector.GroupHeaderTemplate>
注意代码里的“{Binding Title}”,这个绑定的就是组名,即刚才Group<T>类里面的Title属性,如果你不希望它叫Title可以直接改Group<T>类。