Windows Phone版本号自升入8.1以来,开发者就多了一个选项,开发基于WinRT架构的WP或者Universal Windows App。然而开发框架转为WinRT后,很多原有的WP8基于Sliverlight框架的控件和方法变得不再有效,这无疑带来较大的困扰。今天我要讲述的就是此类问题中较易出现的列表拼音分组方案,本文基于WinRT架构予以实现,下面附上实现效果图:

解决方案:

在WP8下,Silverlight提供了LongListSelector控件,可以方便的实现以上的拼音分组效果,具体实现方法可以参考以下博文:

http://diaosbook.com/Post/2014/2/22/longlistselector-group-by-py-wp8

但是WP8.1则不然,WinRT框架默认不提供分组控件,唯一的解决办法是我们使用相关控件自己来实现。我讲此方案归纳为SemanticZoom+ListView+GridView+ValueConverter=LongListSelector,不得不说,这样实现的复杂度远大于Silverlight框架,但其自定义程度高的优势也很明显。

1.数据分组

我们要在正常列表视图下展示分组的列表,这需要我们提前做好数据的分组,对于这一点,官方提供了多种方案,最简单的就是给List中每一项都提供Key属性,这样处理起来最简单,但却十分麻烦,需要我们在数据源里提前设计好Key属性,所以这里我并不会讲述这种分组方法。

我要讲述的是通用程度较高的分组方案,不需要在数据源中设计好Key属性,而是按照正常的方式使用数据源,但是我们会对数据源进行分组处理,最后讲分组后的数据绑定到ListView控件,当然,我们的分组处理行为都是在后台自动处理的。

首先为了ListView控件能够展示分组数据,需要将它的Itemssource绑定到CollectionViewSource数据源,CollectionViewSource数据源IsGrouped属性必须设置为True,Source属性绑定到我们提供的分组数据。

<vm:MainPage_Model x:Name="MainVM" x:Key="DesignVM"/>
<CollectionViewSource x:Name="GroupData" x:Key="GroupData" IsSourceGrouped="True"  Source="{Binding StartCityGroup, Source={StaticResource DesignVM}}"/>

后台处理:

I. 这里我们创建一个辅助类,参考MSDN的文章方案,我进行了修改适应,实现如下:

//将输入的数据源进行拼音分组,返回CollectionViewSource可以接受的数据结构public class AlphaKeyGroup<T>:List<T>{const string GlobeGroupKey = "?";public string Key { get; private set; }//public List<T> this { get; private set; }public AlphaKeyGroup(string key){Key = key;}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;else if (cg.Label == "...") { list.Add(new AlphaKeyGroup<T>(GlobeGroupKey)); }elselist.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(alphagroupkey => (alphagroupkey.Key.Equals(label, StringComparison.CurrentCulture)));if (index > -1 && index < list.Count) list[index].Add(item);}if (sort){foreach (AlphaKeyGroup<T> group in list){group.Sort((c0, c1) => { return keySelector(c0).CompareTo(keySelector(c1)); });}}return list;}}

II. 添加可用于绑定到CollectionViewSource的List<AlphaKeyGroup<City>>属性,这里的City是自定义数据模型,如下:

//这里的代码是MVVM-Sidekick框架自动生成的,主要就是第一行的定义代码public List<AlphaKeyGroup<City>> StartCityGroup{get { return _StartCityGroupLocator(this).Value; }set { _StartCityGroupLocator(this).SetValueAndTryNotify(value); }}#region Property List<AlphaKeyGroup<City>> StartCityGroup Setupprotected Property<List<AlphaKeyGroup<City>>> _StartCityGroup = new Property<List<AlphaKeyGroup<City>>> { LocatorFunc = _StartCityGroupLocator };static Func<BindableBase, ValueContainer<List<AlphaKeyGroup<City>>>> _StartCityGroupLocator = RegisterContainerLocator<List<AlphaKeyGroup<City>>>("StartCityGroup", model => model.Initialize("StartCityGroup", ref model._StartCityGroup, ref _StartCityGroupLocator, _StartCityGroupDefaultValueFactory));static Func<BindableBase, List<AlphaKeyGroup<City>>> _StartCityGroupDefaultValueFactory =model =>{var vm = CastToCurrentType(model);//TODO: Add the logic that produce default value from vm current status.return default(List<AlphaKeyGroup<City>>);};#endregion

III. 给StartCityGrup赋予数据,这里就用到我们的辅助类了,实现如下:

//StartCity是List<City>类型的源数据集合
StartCityGroup = AlphaKeyGroup<City>.CreateGroups(StartCity, (City s) => { return s.Name; }, true);

这里因为我们要根据城市名称拼音分组,所以使用了对应的Name属性。

2.绑定视图

还需要设置ListView分组标头,设置GrupStyle,如下:

<ListView Margin="15,10" x:Name="StartCityList" ItemsSource="{Binding Source={StaticResource GroupData}}"  Foreground="Black" Background="White" SelectionChanged="StartCityList_SelectionChanged" ><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><ListView.ItemTemplate><DataTemplate><StackPanel Orientation="Horizontal"><TextBlock Text="{Binding Name}" FontSize="20"/><TextBlock Margin="10,0,0,0" FontSize="20" Text="{Binding CityCode}"/></StackPanel></DataTemplate></ListView.ItemTemplate></ListView>

到了这里,ListView就可以实现拼音分组显示了。

IV.实现分组拼音跳转

这里就需要使用GridView和SemanticZoom控件,GridView控件用于显示拼音字母集合,SemanticZoom实现视图切换,实现代码如下:

<SemanticZoom  Background="White" x:Name="semanticZoom" ViewChangeStarted="SemanticZoom_ViewChangeStarted"><SemanticZoom.ZoomedInView><ListView Margin="15,10" x:Name="StartCityList" ItemsSource="{Binding Source={StaticResource GroupData}}"  Foreground="Black" Background="White" SelectionChanged="StartCityList_SelectionChanged" ><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><ListView.ItemTemplate><DataTemplate><StackPanel Orientation="Horizontal"><TextBlock Text="{Binding Name}" FontSize="20"/><TextBlock Margin="10,0,0,0" FontSize="20" Text="{Binding CityCode}"/></StackPanel></DataTemplate></ListView.ItemTemplate></ListView></SemanticZoom.ZoomedInView><SemanticZoom.ZoomedOutView><!-- 缩放后的跳转界面 --><GridView x:Name="ZoomGridView"  ItemsSource="{Binding View.CollectionGroups ,Source={StaticResource GroupData}}" HorizontalAlignment="Center" Background="Gray" VerticalAlignment="Center"><GridView.ItemTemplate><DataTemplate><Border Background="White" ><Border Margin="2" Width="90" Height="90" HorizontalAlignment="Left" Background="{Binding Group.Count,Converter={StaticResource BackgroundConverter}}"><TextBlock Text="{Binding Group.Key}" Foreground="White" FontSize="48" Padding="6" HorizontalAlignment="Left" VerticalAlignment="Center"/></Border></Border></DataTemplate></GridView.ItemTemplate></GridView></SemanticZoom.ZoomedOutView></SemanticZoom>

这里需要注意一下,ListView和GridView使用同一个CollectionViewSource作为数据源时,可以实现自动分组跳转,不需要多余的代码。如果不是,则需要使用SemanticZoom控件的ViewChangeCompleted和ViewChangeStarted进行代码控制实现。

V. 实现分组标头颜色区分

这里我自定义了一个IValueConverter来进行GridView项显示颜色的转化,这里根据绑定分组数据的数量来区分,如果此分组有对应的数据则显示蓝色,如果分组数据为空,则显示为灰色,实际效果如第二张图片。

转换器实现代码:

class BackgroundConverter:IValueConverter{public object Convert(object value, Type targetType, object parameter, string language){if(value!=null){var count = int.Parse(value.ToString());if (count > 0)return new SolidColorBrush(Windows.UI.Colors.Blue);}return new SolidColorBrush(Windows.UI.Colors.Gray);}public object ConvertBack(object value, Type targetType, object parameter, string language){throw new NotImplementedException();}}

总结:

WinRT框架的实现拼音分组控件虽然复杂程度大增,但是其功能区的高度可自定义化,无疑是较大的进步,我想微软会在后续的更新中推出更好的控件或解决方案,希望这篇文章对于开发WinRT框架app的你有所帮助。

转载于:https://www.cnblogs.com/mantgh/p/4049031.html

Windows Phone开发手记-WinRT下分组拼音的实现相关推荐

  1. Windows Phone开发手记-WinRT下启动器替代方案

    在WP7/8时代,Silverlight框架提供了很多启动器API,我们可以很方便的使用的,来完成一些系统级的操作.但是随着Win RT架构的WP8.1(SL 8.1除外)的到来,原有的SL下的启动器 ...

  2. Windows驱动开发 - 内核模式下的字符串操作

    1 ASCII字符串和宽字符串 char型,记录ansi字符集.每个字符一个字节.以0标志结束.在KdPrint中用%s输出. 宽字符型,wchar_t,描述unicode字符集的字符串,每个字符两个 ...

  3. Windows Phone开发(11):常用控件(下)

    原文:Windows Phone开发(11):常用控件(下) WP控件大部分都可以从Silverlight中继承过来,这里我也只能拿一部分作演示,对于其它控件如何使用,可以参考SDK相关说明以及Sil ...

  4. windows RT开发笔记:WinRT DLL及其调用研究

    一. 几个概念: WinRT : Windows Runtime, windows运行时.创建Windows运行时(WinRT)是为了在Windows上给用户提供一种流畅且安全的应用体验.WinRT会 ...

  5. Windows Mobile (EVC)开发手记1

    最近开始尝试windows Mobile开发,使用EVC4.0,一开始就遇到了一些问题,一并写下来做个手记. 1.安装开发环境及步骤  操作系统:winxp + sp2 Instructions Th ...

  6. 小啊呜产品读书笔记001:《邱岳的产品手记-10》第19讲 产品经理如何与开发打交道(上):打破思维的边界 第20讲 产品经理如何与开发打交道(下):合作与共赢

    小啊呜产品读书笔记001:<邱岳的产品手记-10>第19讲 产品经理如何与开发打交道(上):打破思维的边界 & 第20讲 产品经理如何与开发打交道(下):合作与共赢 一.今日阅读计 ...

  7. 关于《竹林蹊径 深入浅出Windows驱动开发》第一个例子在Win7下蓝屏

    在尝试运行<竹林蹊径 深入浅出Windows驱动开发>的第一个例子-HelloDRIVER时,在XP下没有问题,但在Win7下却发生蓝屏,蓝屏发生点在于卸载函数DriverUnload. ...

  8. 交通银行香港分行实施 Linux 前端系统的开发手记

    交通银行香港分行实施 Linux 前端系统的开发手记 2004 年被称为是 Linux 应用推广的开端之年.剖开历史巨大的横断面,诸多的 Linux 应用项目如繁星,开始隐隐出现在巨大的苍穹下.它们中 ...

  9. HoloLens开发手记 - HoloLens shell概述 HoloLens shell overview

    使用HoloLens时,shell是由你周围的世界和来自系统的全息图像构成.我们将这种空间成为混合世界(mixed world). shell包含了一个可以让你将全息图像和应用放置在世界中的开始菜单( ...

最新文章

  1. 每日一皮:第一次用CSS的时候,我震惊了...
  2. sysname数据类型是什么
  3. wordpress-4.4.1 数据库表结构详解
  4. 循环查询sql带逗号(,)分隔的数据 以及一对多数据转化为逗号(,)分割数据...
  5. POJ1741 Tree 树中点对统计【树分治入门】
  6. 图论--2-SAT--详解
  7. 可爱的 Python: 使用 mechanize 和 Beautiful Soup 轻松收集 Web 数据
  8. 从 0 开始手写一个 Spring MVC 框架,向高手进阶
  9. spark sql uv_使用Spark Streaming SQL进行PV/UV统计
  10. Qt中如何给按钮加图标(背景图片)
  11. RK3288_Android7.1基于tinyalsa的音频调试说明
  12. python手写数字识别实验报告_ANN MNIST手写数字识别总结
  13. 爱情骗我说有个地方叫地久天长
  14. 使用 OpenSSL 创建ssl自签名证书
  15. java验证用户名和密码_java验证用户名和密码详解
  16. xls解密(实战详细教程)
  17. verilog prbs
  18. 【python爬虫自学笔记】-----爬取简书网站首页文章标题与链接
  19. 多线程实现 qq 群聊的服务端和客户端
  20. 详解美股中的几种交易单-限价单、市价单、止损单、止损限价单、跟踪止损单

热门文章

  1. Linux scp -r命令主机间文件复制
  2. Hadoop MapReduce实例:按照手机号归属地分区统计手机上网流量(Reduce Task进程数设置)
  3. usb管控软件_记账软件新外设:PUPUPULA 智能存钱罐登陆众筹
  4. C++设计模式--状态模式(state)
  5. USB转串口 FT232/PL2303/CH340 比较
  6. Restoring Road Network(弗洛伊德算法的使用)
  7. k8s mysql 配置文件_k8s配置文件模板
  8. U-Boot 之二 详解使用 eclipse + J-Link 进行编译及在线调试
  9. Git 之一 起源、安装、配置
  10. Java内存模型、volatile、原子性、可见性、有序性、happens-before原则