在写一个看新闻软件的时候,用到了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. entityframework学习笔记--008-实体数据建模基础之继承关系映射TPH

    Table per Hierarchy Inheritance 建模 1.让我们假设你有如图8-1中的表,Employee表包含hourly employees 和salaried employees ...

  2. XTemplate语法基础

    XTemplate 是富逻辑的 KISSY 模板引擎,面向复杂的业务逻辑场景,同时保持高性能和丰富的配置方法,是易学易懂的模板语言. 一个典型的XTemplate模板实例: Hello {{name} ...

  3. arcgis 许可异常的解决

    异常现象: arcgis 许可服务管理器中无法重新读取许可,许可服务启动后立即停止.         解决方法: 1.卸载license:安装新的license!重新破解,替换license文件夹BI ...

  4. UIDatePicker

    UIDatePickerDemo 效果 用法 1.导入文件(CustomDatePickerView.h/.m 和UIView+SetRect.h/.m) 2.在所要用到地方导入头文件  #impor ...

  5. Using Dagger2 in Android

    Dagger2是一个Java和Android的依赖注入框架. 本文介绍Android中dagger2的基本使用. 其中包括@Inject, @Component, @Module和@Provides注 ...

  6. linux jexus 服务 设置开机启动

    linux的服务开机设置一般在 /etc/init.d/里 而jexus的默认安装目录在 /usr/jexus里 启动文件为 jws 参数 有start stop restart 这里贡献一个刚写好的 ...

  7. QService 服务容器

    原理 服务容器 服务主体,反射执行业务类 管理器 对服务容器进行控制 测试服务 向一个文件写入内容 启用一个HTTP服务 以下为日志: 2015-06-15 11:50:47.5313 Info QS ...

  8. Tomcat配置内存和远程debug端口

    一.配置内存 在/tomcat/bin/catalina.sh 中添加: JAVA_OPTS='-server -Xms2048m -Xmx2048m -XX:NewSize=768m -XX:Max ...

  9. Python导出Excel为Lua/Json/Xml实例教程(二):xlrd初体验

    Python导出Excel为Lua/Json/Xml实例教程(二):xlrd初体验 相关链接: Python导出Excel为Lua/Json/Xml实例教程(一):初识Python Python导出E ...

  10. XSS 防御方法总结

    1. XSS攻击原理 XSS原称为CSS(Cross-Site Scripting),因为和层叠样式表(Cascading Style Sheets)重名,所以改称为XSS(X一般有未知的含义,还有扩 ...