• [UWP] 使用SemanticZoom控件


    在写一个看新闻软件的时候,用到了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,即BackgroundConverterForegroundConverter

    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

  • 相关阅读:
    通用Logging框架设计
    slf4j 与各个 logging框架的适配器说明
    优雅的使用Spring
    Python : 反射
    Python: Tools
    Python : Class
    Python : Module
    Python 入门:基本语法
    docker:版本变更
    Linux: yum配置说明
  • 原文地址:https://www.cnblogs.com/arcsinw/p/5189789.html
Copyright © 2020-2023  润新知