在写一个看新闻软件的时候,用到了SemanticZoom控件,遇到了一些问题,比如如何根据首字母分类,以及放大视图中有数据的和没数据的通过背景色或前景色区分,幸运的是,all solved。

先来个效果图

主要是参考了msdn的一篇博客,地址已经放在参考链接里了。

首先是一个SemanticZoom控件,这个控件有ZoomedInView和ZoomedOutView两种视图。

ZoomedOutView视图就是这个

而ZoomedInView视图就是一个带有列表头的列表的样子,还是上个图好了,我个人不喜欢看一大段的纯文字

首先弄个Model,这里叫Picture

  public class Picture
{
public string ImageUri { get; set; }
public string Title { get; set; }
}

然后再加个ViewModel,叫MainPageViewModel,类里写一个数据集合和加载数据的方法

  public ObservableCollection<AlphaKeyGroup<Picture>> AllPictures { get; set; }

关于加载数据的方法,很显然,我们要把数据按照Title的首字母分组,按首字母分组说实话我不会,然后我在msdn找到了一个类叫AlphaKeyGroup,这个类可以用来按首字母分组

 public class AlphaKeyGroup<T> : List<T>
{
/// <summary>
/// The delegate that is used to get the key information.
/// </summary>
/// <param name="item">An object of type T</param>
/// <returns>The key value to use for this object</returns>
public delegate string GetKeyDelegate(T item); /// <summary>
/// The Key of this group.
/// </summary>
public string Key { get; private set; } /// <summary>
/// Public constructor.
/// </summary>
/// <param name="key">The key for this group.</param>
public AlphaKeyGroup(string key)
{
Key = key;
} /// <summary>
/// Create a list of AlphaGroup<T> with keys set by a SortedLocaleGrouping.
/// </summary>
/// <param name="slg">The </param>
/// <returns>Theitems source for a LongListSelector</returns>
private static List<AlphaKeyGroup<T>> CreateGroups(SortedLocaleGrouping slg)
{
List<AlphaKeyGroup<T>> list = new List<AlphaKeyGroup<T>>(); foreach (string key in slg.GroupDisplayNames)
{
list.Add(new AlphaKeyGroup<T>(key));
} return list;
} /// <summary>
/// Create a list of AlphaGroup<T> with keys set by a SortedLocaleGrouping.
/// </summary>
/// <param name="items">The items to place in the groups.</param>
/// <param name="ci">The CultureInfo to group and sort by.</param>
/// <param name="getKey">A delegate to get the key from an item.</param>
/// <param name="sort">Will sort the data if true.</param>
/// <returns>An items source for a LongListSelector</returns>
public static List<AlphaKeyGroup<T>> CreateGroups(IEnumerable<T> items, CultureInfo ci, GetKeyDelegate getKey, bool sort)
{
SortedLocaleGrouping slg = new SortedLocaleGrouping(ci);
List<AlphaKeyGroup<T>> list = CreateGroups(slg); foreach (T item in items)
{
int index = ;
if (slg.SupportsPhonetics)
{
//check if your database has yomi string for item
//if it does not, then do you want to generate Yomi or ask the user for this item.
//index = slg.GetGroupIndex(getKey(Yomiof(item)));
}
else
{
index = slg.GetGroupIndex(getKey(item));
}
if (index >= && index < list.Count)
{
list[index].Add(item);
}
} if (sort)
{
foreach (AlphaKeyGroup<T> group in list)
{
group.Sort((c0, c1) => { return ci.CompareInfo.Compare(getKey(c0), getKey(c1)); });
}
} return list;
} }

AlphaKeyGroup

使用的时候这样,CreateGroups方法有三个参数,第一个是要分组的数据,第二个参数是分组的方法,第三个参数是是否排序,该方法返回了一个List<AlphaKeyGroup<Picture>>类型的数据,

  //按拼音分组
List<AlphaKeyGroup<Picture>> groupData = AlphaKeyGroup<Picture>.CreateGroups(
picturesList, (Picture s) => s.Title, true); foreach (var item in groupData)
{
AllPictures.Add(item);
}

当然首先要在picturesList里加一些示例数据

  picturesList.Add(new Picture { ImageUri = "http://t3.gstatic.com/images?q=tbn:ANd9GcQ_ih-aN2gxUz435mPC733IFDNhk1vqFQSVKshWMHEtzxKfKqbs", Title = "OOO" });
picturesList.Add(new Picture { ImageUri = "http://4.bp.blogspot.com/-v4cAAv3ViZk/T3w0jsZocUI/AAAAAAAACE0/l21tSjKnSUI/s640/Cool_facebook_timeline_covers+%252814%2529.jpg", Title = "ZZZ" });
picturesList.Add(new Picture { ImageUri = "http://t3.gstatic.com/images?q=tbn:ANd9GcTv1Kx5oic3I39RTIoAMrFOKQxaIKNtXSNSr5B5bUGsX5mRMMBl_Q", Title = "DDD" });
picturesList.Add(new Picture { ImageUri = "http://t0.gstatic.com/images?q=tbn:ANd9GcRFzgy_qOhDZ3GAQVxIOi1oTg8VSToo8hX_0cxoD6ZqUW9K-r9p", Title = "BBB" });

然后开始写UI部分,当然要先把Page的DataContext设置到MainPageViewModel的实例,比较简单这里就不写了, 再在Xaml里加上一个CollectionViewSource,用来给SemanticZoom提供数据,ItemsPath填的是集合属性的名字,至于为什么填这个,看看AlphaKeyGroup类的源码就知道了,里面有个List<T>类型的 InternalList,数据就是被存在这里的,IsSourceGrouped意思是要把AllPictures分组

 <CollectionViewSource x:Key="CollectionViewSource" IsSourceGrouped="True"
ItemsPath="InternalList"
Source="{Binding AllPictures}"/>

开始写SemanticZoom

 <SemanticZoom >
<SemanticZoom.Style>
<Style TargetType="SemanticZoom">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</SemanticZoom.Style>
<!--数据列表-->
<SemanticZoom.ZoomedInView>
<ListView ItemsSource="{Binding Source={StaticResource CollectionViewSource}}"
SelectionMode="None"
ShowsScrollingPlaceholders="True"
IsItemClickEnabled="True"
ItemClick="ListView_ItemClick">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Padding="0,8"
BorderThickness="{StaticResource BorderThickness}"
BorderBrush="{StaticResource BorderBrush}" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Stretch="Fill" HorizontalAlignment="Left" >
<Image.Source>
<BitmapImage UriSource="{Binding imageUri}"/>
</Image.Source>
</Image>
<Grid Grid.Column="1" Margin="5,2">
<TextBlock Text="{Binding Title}" VerticalAlignment="Top" TextWrapping="Wrap"/>
</Grid>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Margin" Value="0"/>
</Style>
</ListView.ItemContainerStyle>
<!--列表头-->
<ListView.GroupStyle>
<GroupStyle HidesIfEmpty="True" >
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Key}" FontSize="25" Foreground="Red"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
</SemanticZoom.ZoomedInView>
<!--排序列表-->
<SemanticZoom.ZoomedOutView>
<GridView ItemsSource="{Binding Source={StaticResource CollectionViewSource},Path=CollectionGroups}">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid MaximumRowsOrColumns="4" VerticalAlignment="Top" Orientation="Horizontal"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemTemplate>
<DataTemplate>
<Border Background="{Binding Converter={StaticResource BackgroundConverter}}">
<TextBlock Text="{Binding Group.Key}" HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{Binding Converter={StaticResource ForegroundConverter}}"/>
</Border>
</DataTemplate>
</GridView.ItemTemplate> <GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
</Style>
</GridView.ItemContainerStyle>
<GridView.Template>
<ControlTemplate>
<ScrollViewer ScrollViewer.VerticalScrollMode="Enabled">
<Viewbox Stretch="Uniform" Margin="8" VerticalAlignment="Top"
ScrollViewer.VerticalScrollMode="Enabled" StretchDirection="Both" >
<ItemsPresenter />
</Viewbox>
</ScrollViewer>
</ControlTemplate>
</GridView.Template>
</GridView>
</SemanticZoom.ZoomedOutView>
</SemanticZoom>

SemanticZoom

注意到排序列表的GridView.ItemTemplate ,用到了两个Converter,即BackgroundConverter和ForegroundConverter

      <Border Background="{Binding Converter={StaticResource BackgroundConverter}}">
<TextBlock Text="{Binding Group.Key}" HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{Binding Converter={StaticResource ForegroundConverter}}"/>
</Border>

我一直想实现在ZoomedOutView里那种有数据的和没数据的用颜色区分的功能,自己写Converter没写出来,然后发现了这个

这两个Converter是系统自带的,用的时候设置好Enabled和Disabled的颜色,有数据的时候显示Enabled的颜色,没有就显示Disabled的颜色

 <JumpListItemBackgroundConverter x:Key="BackgroundConverter" Enabled="Red"
Disabled="Transparent"/>
<JumpListItemBackgroundConverter x:Key="ForegroundConverter" Enabled="White" Disabled="Black"/>

附上demo

SemanticZoomDemo

还有一个待解决的问题,在ZoomOutView中如何将无数据的项变成不可点击状态?既然那两个Converter能知道哪个是没数据的,说明一定有办法,Pending……

参考链接

http://blogs.msdn.com/b/msgulfcommunity/archive/2013/06/18/implementing-longlistselector-as-jumplists-in-windows-phone-8-alphabetical-list.aspx

[UWP] 使用SemanticZoom控件的更多相关文章

  1. [WP8.1UI控件编程]SemanticZoom控件实现分组列表

    11.1.5 SemanticZoom实现分组列表 SemanticZoom控件可以让用户实现一种更加高级的列表,这种列表可以对列表的项目进行分组,同时这个SemanticZoom控件会提供两个具有相 ...

  2. UWP 用Thumb 控件仿制一个可拖动悬浮 Button

    参考了 http://www.cnblogs.com/zhanggaoxing/p/6403430.html,并加以改进. 最终效果::: Thumb 的原生事件 DragStarted,DragDe ...

  3. UWP开发之控件:用WebView做聊天框

    目录 说明 WebView存在的价值 使用WebView的几个重要技巧 使用WebView做的聊天框 说明 大家都知道,无论是之前的Winform.WPF还是现在的IOS.Android开发中,都存在 ...

  4. UWP自动填充控件AutoSuggestBox小优化

    UWP提供的AutoSuggestBox本身非常好用,在项目中经常用到,但是当我们使用时发现一下不人性化的设置,例子1如下: <Page x:Class="SelfInkCanvas. ...

  5. [UWP]实现Picker控件

    1. 前言 在WPF中,很多打开下拉框(Popup或Flyout)选择一个结果值的控件,除了ComboBox等少数例外,这种控件都以-Picker做名称后缀.因为要打开关闭下拉框和计算下拉框的弹出位置 ...

  6. UWP 播放媒体控件

    最近我的uwp需要有一个有声朗读的功能,like this 点击声音按钮就可以有声朗读了.这里主要是用了媒体播放的控件. 一般我们把需求分为两种: 一种是不需要呈现播放器的样子,只需要用户点击一下别的 ...

  7. win10 uwp 绘图 Line 控件使用

    本文主要讲一个在绘图中,我们会有一个基础的控件,Line.控件的基本使用和他能做出的我们很多时候需要的界面. 虽然是一个简单控件,但是可以做出很诡异的很好看的UI. 首先,我们要知道,Line就是画直 ...

  8. UWP Flyout浮动控件

    看见没,点击"Options"按钮,浮动出来一个界面,这个界面可以用xaml自定义. 如果要点击的控件又Flyout属性那么,可以直接按照下面用 <Button Conten ...

  9. Windows UWP开发系列 – 控件默认样式

    今天用一个Pivot控件的时候,想修改一下它的Header样式,却发现用Blend和VS无法导出它的默认样式了,导致无法下手,不知道是不是Blend的bug. 在网上搜了一下,在MSDN上还是找到了它 ...

随机推荐

  1. 设计模式03备忘录(java)

    先贴代码有空来写内容. 备忘录1 //简单的备忘录,只可以记录上一次修改前的状态,实现撤回一次的操作. class Student{ private String name; private Stri ...

  2. Canvas的width,height 和 样式中Canvas的width,height

    控制Canvas的大小,有两种方式: 1:直接设置Canvas标签上的书width,height属性值; 2:通过Css设置Canvas的width,height; 这两种方式,区别是很大的. 1:C ...

  3. tomcat项目中文乱码问题解决方法

    在部署tomcat项目时经常会遇到中文乱码问题,解决的方法可参考以下步骤. 1.更改Tomcat安装目录下的conf\server.xml,指定浏览器的编码格式为"utf-8"格式 ...

  4. elasticsearch__5__java操作之FilterBuilders构建过滤器Query

    FilterBuilders构建过滤器Query 代码如下: package com.elasticsearch; import org.elasticsearch.action.ActionList ...

  5. iOS sqlite 的各种操作

    iOS --SQL的增加.删除.查找.修改 iOS对于数据库的操作:增加.删除.查找.修改 首先需要创建一个数据库:本程序的数据库是在火狐浏览器里的插件里写的微量型数据库 火狐找查找SQLite Ma ...

  6. JavaSE 之 final 初探

    我们先看一道面试题: 请问 final 的含义是什么?可以用在哪里?其初始化的方式有哪些? 首先我们回答一下这道题,然后再探究其所以然.  1.final 表示“最终的”.“不可改变的”,意指其修饰类 ...

  7. C# 知识特性 Attribute

    C#知识--获取特性 Attribute 特性提供功能强大的方法,用以将元数据或声明信息与代码(程序集.类型.方法.属性等)相关联.特性与程序实体关联后,可在运行时使用"反射"查询 ...

  8. [MySQL Reference Manual] 24 MySQL sys框架

    24 MySQL sys框架 24 MySQL sys框架 24.1 sys框架的前提条件 24.2 使用sys框架 24.3 sys框架进度报告 24.4 sys框架的对象 24.4.1所有sys下 ...

  9. Windows 10不能拨L2TP协议的VPN

    之前是Windows 10版本1607版本14393.102升级14393.187过后,突然出现不能拨公司防火墙的L2TPVPN了. 网上众说纷纭,原来遇到这个问题的人真不少,不过我是第一次遇到.结合 ...

  10. 一个C++版的嵌入式操作系统

     原创文章,转载请注明出处! 现世面上流传着很多嵌入式操作系统,都已经非常优秀,但本人(Sam的博客-博客园)还是自己编写了一个RTOS,不敢说优秀,但绝对是使用起来最简单的.先看一个工程截图与一段m ...