当前位置: 移动技术网 > IT编程>移动开发>WP > [UWP] 使用SemanticZoom控件

[UWP] 使用SemanticZoom控件

2018年01月11日  | 移动技术网IT编程  | 我要评论

俞思妍,李蔚语,猫天使一号

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

先来个效果图

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

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

ZoomedOutView视图就是这个

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

 

首先弄个Model,这里叫Picture

1  public class Picture
2     {
3         public string ImageUri { get; set; }
4         public string Title { get; set; }
5     }

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

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

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

 1 public class AlphaKeyGroup<T> : List<T>
 2     {
 3         /// <summary>
 4         /// The delegate that is used to get the key information.
 5         /// </summary>
 6         /// <param name="item">An object of type T</param>
 7         /// <returns>The key value to use for this object</returns>
 8         public delegate string GetKeyDelegate(T item);
 9 
10         /// <summary>
11         /// The Key of this group.
12         /// </summary>
13         public string Key { get; private set; }
14 
15         /// <summary>
16         /// Public constructor.
17         /// </summary>
18         /// <param name="key">The key for this group.</param>
19         public AlphaKeyGroup(string key)
20         {
21             Key = key;
22         }
23 
24         /// <summary>
25         /// Create a list of AlphaGroup<T> with keys set by a SortedLocaleGrouping.
26         /// </summary>
27         /// <param name="slg">The </param>
28         /// <returns>Theitems source for a LongListSelector</returns>
29         private static List<AlphaKeyGroup<T>> CreateGroups(SortedLocaleGrouping slg)
30         {
31             List<AlphaKeyGroup<T>> list = new List<AlphaKeyGroup<T>>();
32 
33             foreach (string key in slg.GroupDisplayNames)
34             {
35                 list.Add(new AlphaKeyGroup<T>(key));
36             }
37 
38             return list;
39         }
40 
41         /// <summary>
42         /// Create a list of AlphaGroup<T> with keys set by a SortedLocaleGrouping.
43         /// </summary>
44         /// <param name="items">The items to place in the groups.</param>
45         /// <param name="ci">The CultureInfo to group and sort by.</param>
46         /// <param name="getKey">A delegate to get the key from an item.</param>
47         /// <param name="sort">Will sort the data if true.</param>
48         /// <returns>An items source for a LongListSelector</returns>
49         public static List<AlphaKeyGroup<T>> CreateGroups(IEnumerable<T> items, CultureInfo ci, GetKeyDelegate getKey, bool sort)
50         {
51             SortedLocaleGrouping slg = new SortedLocaleGrouping(ci);
52             List<AlphaKeyGroup<T>> list = CreateGroups(slg);
53 
54             foreach (T item in items)
55             {
56                 int index = 0;
57                 if (slg.SupportsPhonetics)
58                 {
59                     //check if your database has yomi string for item
60                     //if it does not, then do you want to generate Yomi or ask the user for this item.
61                     //index = slg.GetGroupIndex(getKey(Yomiof(item)));
62                 }
63                 else
64                 {
65                     index = slg.GetGroupIndex(getKey(item));
66                 }
67                 if (index >= 0 && index < list.Count)
68                 {
69                     list[index].Add(item);
70                 }
71             }
72 
73             if (sort)
74             {
75                 foreach (AlphaKeyGroup<T> group in list)
76                 {
77                     group.Sort((c0, c1) => { return ci.CompareInfo.Compare(getKey(c0), getKey(c1)); });
78                 }
79             }
80 
81             return list;
82         }
83 
84     }
AlphaKeyGroup

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

1  //按拼音分组
2  List<AlphaKeyGroup<Picture>> groupData = AlphaKeyGroup<Picture>.CreateGroups(
3                 picturesList, (Picture s) => s.Title, true);
4 
5  foreach (var item in groupData)
6  {
7      AllPictures.Add(item);
8  }

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

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

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

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

开始写SemanticZoom

 1 <SemanticZoom >
 2             <SemanticZoom.Style>
 3                 <Style TargetType="SemanticZoom">
 4                     <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
 5                 </Style>
 6             </SemanticZoom.Style>
 7             <!--数据列表-->
 8             <SemanticZoom.ZoomedInView>
 9                 <ListView ItemsSource="{Binding Source={StaticResource CollectionViewSource}}"
10                                   SelectionMode="None" 
11                                   ShowsScrollingPlaceholders="True"
12                                   IsItemClickEnabled="True"
13                                   ItemClick="ListView_ItemClick">
14                     <ListView.ItemTemplate>
15                         <DataTemplate>
16                             <Grid  Padding="0,8"
17                                    BorderThickness="{StaticResource BorderThickness}" 
18                                    BorderBrush="{StaticResource BorderBrush}" >
19                                 <Grid.ColumnDefinitions>
20                                     <ColumnDefinition Width="2*"/>
21                                     <ColumnDefinition Width="3*"/>
22                                     <ColumnDefinition Width="Auto"/>
23                                 </Grid.ColumnDefinitions>
24                                 <Image Grid.Column="0" Stretch="Fill" HorizontalAlignment="Left" >
25                                     <Image.Source>
26                                         <BitmapImage UriSource="{Binding imageUri}"/>
27                                     </Image.Source>
28                                 </Image>
29                                 <Grid Grid.Column="1" Margin="5,2">
30                                     <TextBlock Text="{Binding Title}" VerticalAlignment="Top" TextWrapping="Wrap"/>
31                                 </Grid>
32                             </Grid>
33                         </DataTemplate>
34                     </ListView.ItemTemplate>
35                     <ListView.ItemContainerStyle>
36                         <Style TargetType="ListViewItem">
37                             <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
38                             <Setter Property="Margin" Value="0"/>
39                         </Style>
40                     </ListView.ItemContainerStyle>
41                     <!--列表头-->
42                     <ListView.GroupStyle>
43                         <GroupStyle HidesIfEmpty="True" >
44                             <GroupStyle.HeaderTemplate>
45                                 <DataTemplate>
46                                     <TextBlock Text="{Binding Key}" FontSize="25" Foreground="Red"/>
47                                 </DataTemplate>
48                             </GroupStyle.HeaderTemplate>
49                         </GroupStyle>
50                     </ListView.GroupStyle>
51                 </ListView>
52             </SemanticZoom.ZoomedInView>
53             <!--排序列表-->
54             <SemanticZoom.ZoomedOutView>
55                 <GridView ItemsSource="{Binding Source={StaticResource CollectionViewSource},Path=CollectionGroups}">
56                     <GridView.ItemsPanel>
57                         <ItemsPanelTemplate>
58                             <WrapGrid MaximumRowsOrColumns="4" VerticalAlignment="Top" Orientation="Horizontal"/>
59                         </ItemsPanelTemplate>
60                     </GridView.ItemsPanel>
61                     <GridView.ItemTemplate>
62                         <DataTemplate>
63                             <Border Background="{Binding Converter={StaticResource BackgroundConverter}}">
64                                 <TextBlock Text="{Binding Group.Key}" HorizontalAlignment="Center" 
65                                                    VerticalAlignment="Center"
66                                                    Foreground="{Binding Converter={StaticResource ForegroundConverter}}"/>
67                             </Border>
68                         </DataTemplate>
69                     </GridView.ItemTemplate>
70 
71                     <GridView.ItemContainerStyle>
72                         <Style TargetType="GridViewItem">
73                             <Setter Property="HorizontalAlignment" Value="Center"/>
74                             <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
75                             <Setter Property="VerticalAlignment" Value="Center"/>
76                             <Setter Property="VerticalContentAlignment" Value="Stretch"/>
77                         </Style>
78                     </GridView.ItemContainerStyle>
79                     <GridView.Template>
80                         <ControlTemplate>
81                             <ScrollViewer ScrollViewer.VerticalScrollMode="Enabled">
82                                 <Viewbox Stretch="Uniform" Margin="8"  VerticalAlignment="Top" 
83                                              ScrollViewer.VerticalScrollMode="Enabled" StretchDirection="Both" >
84                                     <ItemsPresenter  />
85                                 </Viewbox>
86                             </ScrollViewer>
87                         </ControlTemplate>
88                     </GridView.Template>
89                 </GridView>
90             </SemanticZoom.ZoomedOutView>
91         </SemanticZoom>
SemanticZoom

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

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

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

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

1 <JumpListItemBackgroundConverter x:Key="BackgroundConverter" Enabled="Red"
2                                          Disabled="Transparent"/>
3 <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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网