【WP7】一个便捷而且比较炫的分组聚类控件:LongListSelector控件的使用
在微软发布的Silverlight Toolkit中,有一个LongListSelector控件,可以作为长列表的显示控件。除去基本的列表功能以外,LongListSelector空间还可以处理分组的列表项,每一组有一个头部,可以显示这个分组的信息。
效果如图所示:
其中蓝色的部分是分组的头部。
此外,LongListSelector还有只显示分组头部,点击自动定位的功能。如图所示:
看到了如此高级的使用,下面我们就具体来看看如何实现这个控件的功能吧!
为了使用Toolbox中的控件,首先我们需要在XAML文件中添加如下的名字空间定义:
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
并在工程的引用中添加Microsoft.Phone.Controls.Toolkit。做好之后,就可以在页面上新建一个LongListSelector的实例了,像使用其它控件一样,添加如下代码:
<toolkit:LongListSelector x:Name="LongList">
</toolkit:LongListSelector>
这样添加的结果仅仅是添加了一个空的控件。为了显示列表内容,我们需要修改LongListSelector控件的如下属性:
1. ItemsSource属性:指向列表内容的源。ItemsSource属性必须继承了IEnumerable接口的类的实例;
2. ItemTemplate属性:指定列表表项的模板,用以显示列表的每一个项;
3. GroupHeaderTemplate属性:指定分组头部的模板,可用以显示分组信息,如分组的名称等等;
4. GroupFooterTemplate属性:指定分组尾部的模板,可用以显示各个分组的额外信息,如“显示更多”;
5. ListHeaderTemplate属性:指定整个控件头部的模板;
6. ListFooterTemplate属性:指定整个控件尾部的模板;
7. GroupItemsPanel属性:指定显示分组名称模式下,放置分组名的容器的模板,常设置为WrapPanel控件;
8. GroupItemTemplate属性:指定显示分组名称模式下,放置分组项的模板,可以显示分组名称等信息。
9. IsFlatList属性:布尔型属性,取值为True时,表示列表不需要分组,ItemsSource中的每一项代表一个表项,是一个Item的DataContext;取值为False时,ItemsSource中的每一项代表一个分组,是GroupHeaderTemplate和GroupFooterTemplate的DataContext,而ItemsSource中每一项的GetEnumerator的返回值是ItemTemplate所要显示的内容的迭代器。
下面以我小组项目中的使用来说明LongListSelector控件的用法。
首先,为了封装一个分组,定义了一个Group类,这个类可以作为配合LongListSelector使用的通用类:
1 public class Group<S, T> : IEnumerable<T>
2 {
3 public Group(S groupItem, IEnumerable<T> items)
4 {
5 this.GroupItem = groupItem;
6 this.Items = new List<T>(items);
7 }
8
9 public override bool Equals(object obj)
10 {
11 Group<S, T> other = obj as Group<S, T>;
12 return (other != null) && (GroupItem.Equals(other.GroupItem));
13 }
14 public override int GetHashCode()
15 {
16 return GroupItem.GetHashCode();
17 }
18
19 public S GroupItem { get; set; }
20 public IList<T> Items { get; set; }
21
22 public IEnumerator<T> GetEnumerator()
23 {
24 return Items.GetEnumerator();
25 }
26
27 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
28 {
29 return Items.GetEnumerator();
30 }
31 }
需要显示LongListSelector的时候,可以使用Linq查询,得到一个经过分组的ItemsSource:
var sessions = from session in agendaviewmodel.Items
group session by session.StartTime into s
orderby s.Key
select new Group<DateTime, SessionViewModel>(s.Key, s);
这个语句执行的结果,就是把agendaviewmodel.Items中所有的项目session,按照session.StartTime分组放入s,在把所有的s按照s.Key排序的结果依次放入Group类中,所得到的集成了IEnumerable的结果存储在sessions里。在我们的SessionViewModel中,有一个属性叫Title,于是在ItemTemplate中,便可以用如下的Binding将 Title显示出来:
<TextBlock Text="{Binding Title}"/>
GroupHeaderTemplate中要显示的东西,则可以直接绑定到Group类里的GroupItem属性:
<TextBlock Text="{Binding GroupItem}"/>
这里的Group类并不是必须的,不过为了层次化的封装可以如此抽象出其功能。
关于LongListSelector的更多细节,可以参考:WP7 LongListSelector in depth
Part1: Visual structure and API http://www.windowsphonegeek.com/articles/wp7-longlistselector-in-depth--part1-visual-structure-and-api
Part2: Data binding scenarios http://www.windowsphonegeek.com/articles/wp7-longlistselector-in-depth--part2-data-binding-scenarios