[UWP] 使用SemanticZoom控件
在写一个看新闻软件的时候,用到了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
还有一个待解决的问题,在ZoomOutView中如何将无数据的项变成不可点击状态?既然那两个Converter能知道哪个是没数据的,说明一定有办法,Pending……
参考链接
[UWP] 使用SemanticZoom控件的更多相关文章
- [WP8.1UI控件编程]SemanticZoom控件实现分组列表
11.1.5 SemanticZoom实现分组列表 SemanticZoom控件可以让用户实现一种更加高级的列表,这种列表可以对列表的项目进行分组,同时这个SemanticZoom控件会提供两个具有相 ...
- UWP 用Thumb 控件仿制一个可拖动悬浮 Button
参考了 http://www.cnblogs.com/zhanggaoxing/p/6403430.html,并加以改进. 最终效果::: Thumb 的原生事件 DragStarted,DragDe ...
- UWP开发之控件:用WebView做聊天框
目录 说明 WebView存在的价值 使用WebView的几个重要技巧 使用WebView做的聊天框 说明 大家都知道,无论是之前的Winform.WPF还是现在的IOS.Android开发中,都存在 ...
- UWP自动填充控件AutoSuggestBox小优化
UWP提供的AutoSuggestBox本身非常好用,在项目中经常用到,但是当我们使用时发现一下不人性化的设置,例子1如下: <Page x:Class="SelfInkCanvas. ...
- [UWP]实现Picker控件
1. 前言 在WPF中,很多打开下拉框(Popup或Flyout)选择一个结果值的控件,除了ComboBox等少数例外,这种控件都以-Picker做名称后缀.因为要打开关闭下拉框和计算下拉框的弹出位置 ...
- UWP 播放媒体控件
最近我的uwp需要有一个有声朗读的功能,like this 点击声音按钮就可以有声朗读了.这里主要是用了媒体播放的控件. 一般我们把需求分为两种: 一种是不需要呈现播放器的样子,只需要用户点击一下别的 ...
- win10 uwp 绘图 Line 控件使用
本文主要讲一个在绘图中,我们会有一个基础的控件,Line.控件的基本使用和他能做出的我们很多时候需要的界面. 虽然是一个简单控件,但是可以做出很诡异的很好看的UI. 首先,我们要知道,Line就是画直 ...
- UWP Flyout浮动控件
看见没,点击"Options"按钮,浮动出来一个界面,这个界面可以用xaml自定义. 如果要点击的控件又Flyout属性那么,可以直接按照下面用 <Button Conten ...
- Windows UWP开发系列 – 控件默认样式
今天用一个Pivot控件的时候,想修改一下它的Header样式,却发现用Blend和VS无法导出它的默认样式了,导致无法下手,不知道是不是Blend的bug. 在网上搜了一下,在MSDN上还是找到了它 ...
随机推荐
- Consul的一个更新:服务端节点故障后重连
研究了一段时间Consul,想写个攻略来着,但太赖了而且表达能力非正常人...今天发现HashiCorp果然接纳大众意见改了点东西.. 场景是: 假如Consul集群内有三个Server Node 时 ...
- yii2的权限管理系统RBAC简单介绍
这里有几个概念 权限: 指用户是否可以执行哪些操作,如:编辑.发布.查看回帖 角色 比如:VIP用户组, 高级会员组,中级会员组,初级会员组 VIP用户组:发帖.回帖.删帖.浏览权限 高级会员组:发帖 ...
- OuNews 简单的新闻客户端应用源码
一直想练习MVP模式开发应用,把学习的RxJava.Retrofit等热门的开源库结合起来,于是写了这么一款新闻阅读软件, 有新闻.图片.视频三大模块,使用Retrofit和Okhttp实现无网读缓存 ...
- vs2010中如何设置Visual Assist方便地使用现成的代码编辑器风格
风格setting可以在下面网站上获取: http://studiostyl.es/ 在VS2010+VA直接使用会有2个显著的问题: 1,有些符号颜色太深,与黑色背景几乎融为一体: 2,光标落入大小 ...
- Html --用简单的<hr>实现多样化分割效果
最基本的:<hr width=300 size=1 color=#5151A2 align=center noshade>. <!--其中 width 规定线条的长度,还可以是百分比 ...
- (二)Spark-Linux环境准备-Java&Python版Spark
Spark-Linux环境准备 视频教程: 1.优酷 2.YouTube 硬软件环境 1.虚拟机:VMware Workstation 12 2.虚拟机操作系统:RedHat5u4,单核,1G内存,2 ...
- SQL语句查数据库中某一列是否有重复项
Select 列名,COUNT(列名)FROM 表名GROUP BY 列名HAVING COUNT( 列名 ) 〉1
- Linux工具快速教程
看到一linux中常用工具使用教程,非常好.猛击下面的地址 github:https://github.com/me115/linuxtools_rst 在线文档:http://linuxtools- ...
- 并行计算提升32K*32K点(32位浮点数) FFT计算速度(4核八线程E3处理器)
对32K*32K的随机数矩阵进行FFT变换,数的格式是32位浮点数.将产生的数据存放在堆上,对每一行数据进行N=32K的FFT,记录32K次fft的时间. 比较串行for循环和并行for循环的运行时间 ...
- spring3系列一
IOC基础 Ioc是什么 Ioc--Inversion of Control 控制反转,不是什么技术,而是一种设计思想.在java开发中,ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对 ...