Windows Phone 8.1 列表控件(2):分组数据

说到 List 控件,Windows Phone 8.1 上推荐使用的是 ListView 和 GridView。

而这两个控件实在太多东西可讲了,于是分成三篇来讲:

(1)基本

(2)分组数据

(3)多数据呈现

ListView 和 GridView 的最大差别就是:ListView 是一条条依序排列的,而 GridView 则是一块块依序排列的,因此
ListView 中的一项就会占据整整一行或者一列,而 GridView 的一项只会占据它应有的大小,一行或一列中可以放置多项。

而两者在其它方面上基本一致,因此下文只对 ListView 进行介绍,GridView 其实也一样的。


分组数据(GroupingData)

分组数据也就是将数据按首字母或自定义属性进行分组,然后用户就能通过点击首字母或自定义属性达到快速定位的目的:

构建过程:

(1)准备已分好组的数据

数据的分组可分为两类,一是根据项的首字母或拼音分组,二是根据项的自身属性分组。

1)首字母或拼音分组


public static List<AlphaKeyGroup<SampleItem>> GetAlphaGroupSampleItems()
{
ObservableCollection<SampleItem> data = new ObservableCollection<SampleItem>();
data.Add(new SampleItem() { Title = "k1", Content = "k1", Image = "ms-appx:/Images/k1.png", Group = "Kill La Kill" });
data.Add(new SampleItem() { Title = "w2", Content = "w2", Image = "ms-appx:/Images/w2.png", Group = "Wu Yu" });
data.Add(new SampleItem() { Title = "k3", Content = "k3", Image = "ms-appx:/Images/k3.png", Group = "Kill La Kill" });
data.Add(new SampleItem() { Title = "t4", Content = "t4", Image = "ms-appx:/Images/t4.png", Group = "Tiger" });
data.Add(new SampleItem() { Title = "t5", Content = "t5", Image = "ms-appx:/Images/t5.png", Group = "Tiger" });
data.Add(new SampleItem() { Title = "x6", Content = "x6", Image = "ms-appx:/Images/x6.png", Group = "Xi De Ni Ya" });
data.Add(new SampleItem() { Title = "x7", Content = "x7", Image = "ms-appx:/Images/x7.png", Group = "Xi De Ni Ya" });
data.Add(new SampleItem() { Title = "x8", Content = "x8", Image = "ms-appx:/Images/x8.png", Group = "Xi De Ni Ya" });
data.Add(new SampleItem() { Title = "x9", Content = "x9", Image = "ms-appx:/Images/x9.png", Group = "Xi De Ni Ya" });
data.Add(new SampleItem() { Title = "x10", Content = "x10", Image = "ms-appx:/Images/x10.png", Group = "Xi De Ni Ya" });
data.Add(new SampleItem() { Title = "x11", Content = "x11", Image = "ms-appx:/Images/x11.png", Group = "Xi De Ni Ya" });

List<AlphaKeyGroup<SampleItem>> groupData = AlphaKeyGroup<SampleItem>.CreateGroups(
data,
(SampleItem s) => { return s.Title; },
true);
return groupData;
}

AlphaKeyGroup 类为自己写的分组类:

public class AlphaKeyGroup<T>
{
const string GlobeGroupKey = "\uD83C\uDF10";

public string Key { get; private set; }

public List<T> InternalList { get; private set; }

public AlphaKeyGroup(string key)
{
Key = key;
InternalList = new List<T>();
}

private static List<AlphaKeyGroup<T>> CreateDefaultGroups(CharacterGroupings slg)
{
List<AlphaKeyGroup<T>> list = new List<AlphaKeyGroup<T>>();

foreach( CharacterGrouping cg in slg )
{
if( cg.Label == "" )
continue;
if( cg.Label == "..." )
{
list.Add(new AlphaKeyGroup<T>(GlobeGroupKey));
}
else
{
list.Add(new AlphaKeyGroup<T>(cg.Label));
}
}

return list;
}

public static List<AlphaKeyGroup<T>> CreateGroups(IEnumerable<T> items, Func<T, string> keySelector, bool sort)
{
CharacterGroupings slg = new CharacterGroupings();
List<AlphaKeyGroup<T>> list = CreateDefaultGroups(slg);

foreach( T item in items )
{
int index = 0;
{
string label = slg.Lookup(keySelector(item));
index = list.FindIndex(alphakeygroup => (alphakeygroup.Key.Equals(label, StringComparison.CurrentCulture)));
}

if( index >= 0 && index < list.Count )
{
list[index].InternalList.Add(item);
}
}

if( sort )
{
foreach( AlphaKeyGroup<T> group in list )
{
group.InternalList.Sort((c0, c1) => { return keySelector(c0).CompareTo(keySelector(c0)); });
}
}

return list;
}
}

AlphaKeyGroup

2)自身属性分组


public static List<KeyedList<string, SampleItem>> GetKeyGroupSampleItems()
{
ObservableCollection<SampleItem> data = new ObservableCollection<SampleItem>();
data.Add(new SampleItem() { Title = "k1", Content = "k1", Image = "ms-appx:/Images/k1.png", Group = "Kill La Kill" });
data.Add(new SampleItem() { Title = "w2", Content = "w2", Image = "ms-appx:/Images/w2.png", Group = "Wu Yu" });
data.Add(new SampleItem() { Title = "k3", Content = "k3", Image = "ms-appx:/Images/k3.png", Group = "Kill La Kill" });
data.Add(new SampleItem() { Title = "t4", Content = "t4", Image = "ms-appx:/Images/t4.png", Group = "Tiger" });
data.Add(new SampleItem() { Title = "t5", Content = "t5", Image = "ms-appx:/Images/t5.png", Group = "Tiger" });
data.Add(new SampleItem() { Title = "x6", Content = "x6", Image = "ms-appx:/Images/x6.png", Group = "Xi De Ni Ya" });
data.Add(new SampleItem() { Title = "x7", Content = "x7", Image = "ms-appx:/Images/x7.png", Group = "Xi De Ni Ya" });
data.Add(new SampleItem() { Title = "x8", Content = "x8", Image = "ms-appx:/Images/x8.png", Group = "Xi De Ni Ya" });
data.Add(new SampleItem() { Title = "x9", Content = "x9", Image = "ms-appx:/Images/x9.png", Group = "Xi De Ni Ya" });
data.Add(new SampleItem() { Title = "x10", Content = "x10", Image = "ms-appx:/Images/x10.png", Group = "Xi De Ni Ya" });
data.Add(new SampleItem() { Title = "x11", Content = "x11", Image = "ms-appx:/Images/x11.png", Group = "Xi De Ni Ya" });

var groupedItems = from item in data
orderby item.Group
group item by item.Group into itemsByGroup
select new KeyedList<string, SampleItem>(itemsByGroup);
return groupedItems.ToList();
}

KeyedList 为自己编写的类:

public class KeyedList<TKey, TItem>: List<TItem>
{
public TKey Key { protected set; get; }

public IEnumerable<TItem> InternalList { protected set; get; }

public KeyedList(TKey key, IEnumerable<TItem> items)
: base(items)
{
Key = key;
InternalList = items;
}

public KeyedList(IGrouping<TKey, TItem> grouping)
: base(grouping)
{
Key = grouping.Key;
InternalList = grouping;
}
}

KeyedList

(2)插入 CollectionViewSource

<Page.Resources>
<CollectionViewSource x:Key="ItemsGrouped"
IsSourceGrouped="True"
ItemsPath="InternalList"
Source="{Binding GroupData, Source={Binding}}"/>
</Page.Resources>

这里的 GroupData 即为第一步中准备好的已分组的数据。

然后将 ListView 的 ItemsSource 绑定为
CollectionViewSources:

<ListView ItemsSource="{Binding Source={StaticResource ItemsGrouped}}"/>

(3)编写 ListView 的 GroupStyle.HeaderTemplate

GroupStyle.HeaderTemplate 也就是 ListView
里每一组的标题的模板,可自由定义:


<ListView.GroupStyle>
<GroupStyle HidesIfEmpty="True" >
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Border Background="{StaticResource PhoneAccentBrush}"
BorderBrush="{StaticResource PhoneAccentBrush}"
BorderThickness="2"
Width="62" Height="62" Margin="0,0,18,0"
HorizontalAlignment="Stretch">
<TextBlock Text="{Binding Key}"
Foreground="{StaticResource PhoneForegroundBrush}"
FontSize="48"
Padding="6"
FontFamily="{StaticResource PhoneFontFamilySemiLight}"
HorizontalAlignment="Left"
VerticalAlignment="Center"/>
</Border>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>

(4)将 ListView 放入 SemanticZoom 里

到目前为止,ListView 已经能正常将分组数据显示在页面上了,最后一步也就是将 ListView
放入 SemanticZoom 控件中。


<SemanticZoom>
<SemanticZoom.ZoomedInView>
<!-- 前三步写好的 ListView -->
</SemanticZoom.ZoomedInView>
<SemanticZoom.ZoomedOutView>
<!-- 缩放后的跳转界面 -->
<GridView ItemsSource="{Binding Source={StaticResource ItemsGrouped}, Path=CollectionGroups}"
Background="#AA000000">
<GridView.ItemTemplate>
<DataTemplate>
<Border Background="{Binding Converter={StaticResource BackgroundConverter}}"
Padding="5">
<Border Background="{Binding}"
Width="82" Height="82"
HorizontalAlignment="Left">
<TextBlock Text="{Binding Group.Key}"
Foreground="{Binding Converter={StaticResource ForegroundConverter}}"
FontSize="48"
Padding="6"
HorizontalAlignment="Left" VerticalAlignment="Center"/>
</Border>
</Border>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</SemanticZoom.ZoomedOutView>
</SemanticZoom>

其中的两个 Converter 是对分组中有无该项的区分显示:

<Page
x:Class="ListControls.GroupListViewPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ListControls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prim="using:Windows.UI.Xaml.Controls.Primitives"
mc:Ignorable="d"
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

<Page.Resources>
<prim:JumpListItemBackgroundConverter x:Key="BackgroundConverter"/>
<prim:JumpListItemForegroundConverter x:Key="ForegroundConverter"/>
</Page.Resources>

</Page

Convertor

Windows Phone 8.1 列表控件(2):分组数据

时间: 2024-10-07 20:27:21

Windows Phone 8.1 列表控件(2):分组数据的相关文章

Windows Phone 8.1 列表控件(1):基本

说到 List 控件,Windows Phone 8.1 上推荐使用的是 ListView 和 GridView. 而这两个控件实在太多东西可讲了,于是分成三篇来讲: (1)基本 (2)分组数据 (3)多数据呈现 ListView 和 GridView 的最大差别就是:ListView 是一条条依序排列的,而 GridView 则是一块块依序排列的,因此 ListView 中的一项就会占据整整一行或者一列,而 GridView 的一项只会占据它应有的大小,一行或一列中可以放置多项. 而两者在其它

Windows Phone 8.1 列表控件(3):多数据呈现

说到 List 控件,Windows Phone 8.1 上推荐使用的是 ListView 和 GridView. 而这两个控件实在太多东西可讲了,于是分成三篇来讲: (1)基本 (2)分组数据 (3)多数据呈现 ListView 和 GridView 的最大差别就是:ListView 是一条条依序排列的,而 GridView 则是一块块依序排列的,因此 ListView 中的一项就会占据整整一行或者一列,而 GridView 的一项只会占据它应有的大小,一行或一列中可以放置多项. 而两者在其它

《深入理解Windows Phone 8.1 UI控件编程》

<深入理解Windows Phone 8.1 UI控件编程>本书基于最新的Windows Phone 8.1 Runtime SDK编写,全面深入地论述了最酷的UI编程技术:实现复杂炫酷的动画.掌握布局原理.列表虚拟化原理.高性能列表实现.图表编程.控件原理等. 目录如下: <深入理解Windows Phone 8 .1 UI控件编程>目录 第1章 深入解析程序界面 1.1 XAML的原理 1.1.1 XAML的概念 1.1.2 XAML页面的编译 1.1.3 动态加载XAML 1

WPF: 实现带全选复选框的列表控件

本文将说明如何创建一个带全选复选框的列表控件.其效果如下图:     这个控件是由一个复选框(CheckBox)与一个 ListView 组合而成.它的操作逻辑: 当选中“全选”时,列表中所有的项目都会被选中:反之,取消选中“全选”时,所有项都会被取消勾选. 在列表中选中部分数据项目时,“全选”框会呈现不确定状态(Indetermine). 由此看出,“全选”复选框与列表项中的复选框达到了双向控制的效果. 其设计思路:首先,创建自定义控件(CheckListView),在其 ControlTem

《深入理解Windows Phone 8.1 UI控件编程》基于最新的Runtime框架

<深入理解Windows Phone 8.1 UI控件编程>本书基于最新的Windows Phone 8.1 Runtime SDK编写,全面深入地论述了最酷的UI编程技术:实现复杂炫酷的动画.掌握布局原理.列表虚拟化原理.高性能列表实现.图表编程.控件原理等.  全书源代码免费下载: http://vdisk.weibo.com/s/zt_pyrfNHoezI 试读章节会在博客园持续更新: [WP8.1UI控件编程]Windows Phone XAML页面的编译 [WP8.1UI控件编程]W

如何控制通达OA的工作流表单列表控件的列输入框

通达OA的工作流表单列表控件只提供了从内部或外部数据源映射选择,但有时需要控制某些列不能输入,有些列录入后,带出其他列的数据,如下图 //通过存货编号取存货信息 function getinventory(cinvcode){ var resobj; jQuery.ajax({type:'POST', url:'/userext/index.php?c=workflow&m=getcinvname', data:{cinvcode:cinvcode}, success:function(res)

Windows应用程序文件格式转换控件LEADTOOLS ePrint Professional

LEADTOOLS ePrint Professional控件是一个多功能一体化文件转换解决方案,它可帮助您将任何Windows应用程序中的文件或图像转换为150种类型的文件,其中包括:PDF, DOC, HTML, TXT, TIFF, JPG, GIF, PNG等等. ePrint Professional包含了两种转换模式 - ePrint printer和ePrint Workstation printer,为您提供不同水平的文件转换控制,您可以更加灵活的进行生产.ePrint prin

iOS开发--自定义列表控件

这两天项目比较闲,在空余之际,尝试自己实现列表控件.从动工到初步完成大概花了一天时间,目前实现了列表的简单功能,后续将考虑加入cell重用机制.惯性特征以及删除cell等功能.项目代码已经放到了github上,地址:https://github.com/wanglichun/CustomTableView. 在实现之前,需要了解列表控件的运行原理,我之前的一篇博客<列表控件实现原理解析>中有介绍.去年由于项目需要,使用lua语言自定义过双重列表(大列表嵌套小列表),这次改用objc实现,实现的

MFC可视化 列表控件的使用

1.应该加入头文件 #include <Atlbase.h> 2.示例 类向导给列表控件绑定变量m_list DWORD   dwExStyle=LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_HEADERDRAGDROP|LVS_EX_ONECLICKACTIVATE|LVS_EX_FLATSB; m_list.ModifyStyle(0,LVS_REPORT|LVS_SINGLESEL|LVS_SHOWSELALWAYS);m_list.SetEx