扩展GridView控件——为内容项添加拖放及分组功能

来源:互联网 发布:凑数字软件 编辑:程序博客网 时间:2024/05/13 19:58

引言

相信大家对GridView都不陌生,是非常有用的控件,用于平铺有序的显示多个内容项。打开任何WinRT应用或者是微软合作商的网站,都会在APP中发现GridView的使用。“Tiles”提供了一个简单易用,平铺方式来组织内容显示。Windows8的开始菜单是最典型的GridView示例。“开始菜单”显示了系统中安装的所有应用程序,而且支持重新排列。

本文源于我们项目的开发人员,他们想在项目中提供与GridView相同的用户体验,想要创建类GridView控件。

网格视图可以显示大小不定的内容项,并且以有序的方式显示。如果各个内容项无序,并且内容尺寸大小相同,GirdView还支持拖拽操作。然而,这些功能并不是默认提供的,需要编写一定的代码才能实现。

本文主要介绍了扩展的GridView控件 - 称为GridViewEx,GridViewEx主要实现GridView控件在不同大小的内容项中的拖拽功能。

背景

。首先了解GridView控件的基本属性和功能,GridView控件包含一些属性集和ItemTemplate中为了实现通过拖拽操作执行重排列功能,必须完成以下三件事:

1.设置的AllowDrop属性为真;

2.设置CanReorderItems属性值为真;

3. 绑定数据源,该数据源必须支持数据修改或支持重排序。例如,使用ObservableCollection或IList数据源。

< GridView  ItemsSource ="{Binding}"  AllowDrop ="True"  CanReorderItems ="True" >     < GridView.ItemTemplate >         < DataTemplate >             < Border  BorderBrush ="Aqua"  BorderThickness ="1"  Background ="Peru" >                 < Grid  Margin ="12" >                     < Grid.RowDefinitions >                         < RowDefinition  />                         < RowDefinition  Height ="Auto" />                     </ Grid.RowDefinitions >                     < TextBlock  Text ="{Binding}" />                     < TextBlock  Grid . Row ="1" > item </ TextBlock >                 </ Grid >             </ Border >         </ DataTemplate >     </ GridView.ItemTemplate > </ GridView >

扩展后的GridView控件使用拖拽操作将会非常方便快捷。

GridViewEx控件

GridViewEx控件弥补了GridView控件,功能如下:

  • 实现项目小组拖拽操作,而不是WrapGrid,StackPanel中,VirtualizingStackPanel等
  • 分组时,实现拖拽功能;

我们也为GridViewEx增加了新建分组的功能,如果用户将内容项拖到控件左边或右边时会触发新建分组操作。

实现拖拽代码:

   1:   公共  GridViewEx:GridView控件
   2:   {
   3:       /// <摘要>
   4:       ///初始化<见CREF =“GridViewEx”/>控件的新实例。
   5:       /// </摘要>
   6:       公共 GridViewEx()
   7:       {
   8:           //见附件样品
   9:       }
  10:   
  11:       私人 无效 GridViewEx_DragItemsStarting(对象发件人,DragItemsStartingEventArgs E)
  12:       {
  13:           //见附件样品
  14:       }
  15:   
  16:       /// <摘要>
  17:       ///存储拖物品进入DragEventArgs.Data.Properties [“项目”]值。
  18:       ///重写此方法,如果您需要设置自定义拖动数据。
  19:       /// </摘要>
  20:       受保护的 虚拟 无效 OnDragStarting(DragItemsStartingEventArgs E)
  21:       {
  22:           //见附件样品
  23:       }

该控件包含几个变量,用来存储拖放内容的索引。OnDragStarting事件在DragEventArgs.Data.Properties [“项目”]中存储拖拽的内容。OnDragStarting需要根据自己的需求重写。

当用户拖拽某一项内容时,需要给用户提示来引导用户将内容放在合适的位置上。标准的GriView对象是通过滑动相邻的内实项来实现的。本文将在GridViewEx中完善此操作。

   1:   /// <摘要>
   2:   ///显示自定义的同时拖动reoder提示。
   3:   /// </摘要>
   4:   保护 覆盖 无效 OnDragOver(DragEventArgs E)
   5:   {
   6:       //见附件样品}
   7:   
   8:   私人 INT GetDragOverIndex(DragEventArgs E)
   9:   {
  10:       //见附件样品
  11:   }

实现拖放代码

首先需要重写GridView.OnDrop方法,该方法会当用户释放某一项内容时触发。重写Ondrop方法,代码如下:

   1:   /// <摘要>
   2:   ///把手病例拖放当它不被Windows.UI.Xaml.Controls.GridView控制支持
   3:   /// </摘要>
   4:   保护 覆盖异步无效 OnDrop(DragEventArgs E)
   5:   {
   6:       //见附件样品
   7:   }

 

OnDrop方法主要实现了内容项从源分组移到目标分组的逻辑代码,以及创建新分组的功能。

添加新分组

如果GrideView通过 IsSourceGrouped值为True来绑定CollectionViewSource情况下,GridView提供分组功能,这就意味着分组必须对数据源进行分组,但GridView没有访问数据的权限。因此本文在执行拖放操作时,实现添加新分组功能。GridViewEx.BeforeDrop事件处理此需求,并且提供更多的数据信息,如DragEventArgs数据。

当用户执行拖放操作时,触发BeforeDrop事件。

   1:   /// <摘要>
   2:   ///执行拖放操作前发生,
   3:   /// </摘要>
   4:   公共 事件的EventHandler <BeforeDropItemsEventArgs> BeforeDrop;
   5:   /// <摘要>
   6:   ///升起的<见CREF =“BeforeDrop”/>事件。
   7:   /// </摘要>
   8:   /// <param name =“E”>为事件的事件数据</ param>。
   9:   受保护的 虚拟 无效 OnBeforeDrop(BeforeDropItemsEventArgs E)
  10:   {
  11:       //见附件样品
  12:   }

BeforeDropItemEventArgs包含关于被拖拽的内容项的重要信息,该信息在OnDrop事件中可使用的。

   1:   /// <摘要>
   2:   在<见CREF =“GridViewEx.BeforeDrop”/> ///事件提供数据。
   3:   /// </摘要>
   4:   公共 密封  BeforeDropItemsEventArgs:System.ComponentModel.CancelEventArgs
   5:   {
   6:       /// <摘要>
   7:       ///获取该被拖动的项目。
   8:       /// </摘要>
   9:       公共 对象项目
  10:       {
  11:           搞定;
  12:       }
  13:       /// <摘要>
  14:       ///获取基础数据源的当前项指标。
  15:       /// </摘要>
  16:       公共 INT OldIndex
  17:       {
  18:           搞定;
  19:       }
  20:       /// <摘要>
  21:       ///获取该指数的基础数据源在哪里
  22:       ///该项目将被拖放操作被插入。
  23:       /// </摘要>
  24:       公共 INT NewIndex
  25:       {
  26:           搞定;
  27:       }
  28:       /// <摘要>
  29:       ///获取布尔值确定最终用户的行为是否请求
  30:       在基础数据源创建///新组。
  31:       ///此属性才有意义,如果GridViewEx.IsGrouping属性为true。
  32:       /// </摘要>
  33:       /// <讲话>
  34:       ///如果此属性为true,创建新的数据组,并将其插入
  35:       ///在位置组集合,由指定的
  36:       /// <见CREF =“BeforeDropItemsEventArgs.NewGroupIndex”/>属性值。
  37:       ///那么<见CREF =“GridViewEx”/>将插入拖项目
  38:       ///到新添加的组。
  39:       /// </说明>
  40:       公共 布尔 RequestCreateNewGroup
  41:       {
  42:           搞定;
  43:       }
  44:       /// <摘要>
  45:       ///获取基础数据源的当前项数据组索引。
  46:       ///此属性才有意义,如果GridViewEx.IsGrouping属性为true。
  47:       /// </摘要>
  48:       公共 INT OldGroupIndex
  49:       {
  50:           搞定;
  51:       }
  52:       /// <摘要>
  53:       ///获取基础数据源中的数据组索引
  54:       ///其中项目将被拖放操作被插入。
  55:       ///此属性才有意义,如果GridViewEx.IsGrouping属性为true。
  56:       /// </摘要>
  57:       公共 INT NewGroupIndex
  58:       {
  59:           搞定;
  60:       }
  61:       /// <摘要>
  62:       ///获取原始<见CREF =“DragEventArgs”/>数据。
  63:       /// </摘要>
  64:       公共 DragEventArgs DragEventArgs
  65:       {
  66:           搞定;
  67:       }
  68:   }

AllowNewGroup属性确定用户拖拽某一内容项到控件边界时,是否创建新组。GridView并没有提供此功能,在GridViewEX添加此功能。

   1:   /// <摘要>
   2:   ///获取或设置值,确定是否新组应在创建
   3:   ///拖动项为空的空间。
   4:   /// </摘要>
   5:   公共 布尔 AllowNewGroup
   6:   {
   7:       获取{ 回报布尔)的GetValue(AllowNewGroupProperty); }
   8:       集合{的SetValue(AllowNewGroupProperty,价值); }
   9:   }
  10:   
  11:   /// <摘要>
  12:   ///标识<见CREF =“AllowNewGroup”/>依赖属性。
  13:   /// </摘要>
  14:   公共 静态 只读的DependencyProperty AllowNewGroupProperty =
  15:           DependencyProperty.Register(“AllowNewGroup” typeof运算布尔
  16:           typeof运算(GridViewEx), PropertyMetadata());

为了在拖拽过程中添加分组,需要将AllowNewGroup属性设置为True。处理GridViewEx.BeforeDrop事件,该事件的参数能够帮助决定单项内容的起始位置和目的位置。在BeforeDrop事件的Handler中,使用NewGroupIndex创建新的数据组,并插入到已有组集合。最后,需要实现的扩展GridView控件模板。在用户可拖拽的项目的位置创建新分组,并使用占位符来代替。一旦用户拖某一内容放置到控件的边界时,触发创建新分组,ItemsPresenter的两个边界元素是新组的占位符。

GridViewEx控件模板generic.xaml,如下:

   1:   <样式的TargetType = “本地:GridViewEx” >
   2:       <setter属性= “填充”值= “0,0,0,10” />
   3:       <setter属性= “IsTabStop”值= “FALSE” />
   4:       <setter属性= “TabNavigation”值= “一次” />
   5:       <setter属性= “ScrollViewer.HorizontalScrollBarVisibility”值= “自动” />
   6:       <setter属性= “ScrollViewer.VerticalScrollBarVisibility”值= “禁用” />
   7:       <setter属性= “ScrollViewer.HorizontalScrollMode”值= “已启用” />
   8:       <setter属性= “ScrollViewer.IsHorizontalRailEnabled”值= “FALSE” />
   9:       <setter属性= “ScrollViewer.VerticalScrollMode”值= “禁用” />
  10:       <setter属性= “ScrollViewer.IsVerticalRailEnabled”值= “FALSE” />
  11:       <setter属性= “ScrollViewer.ZoomMode”值= “禁用” />
  12:       <setter属性= “ScrollViewer.IsDeferredScrollingEnabled”值= “FALSE” />
  13:       <setter属性= “ScrollViewer.BringIntoViewOnFocusChange”值= “真” />
  14:       <setter属性= “IsSwipeEnabled”值= “真” />
  15:       <setter属性= “模板” >
  16:           <Setter.Value>
  17:               <ControlTemplate中的TargetType = “本地:GridViewEx” >
  18:                   <边框BorderBrush = “{TemplateBinding BorderBrush}”
  19:                           背景= “{TemplateBinding背景}”
  20:                           了borderThickness = “{TemplateBinding了borderThickness}” >
  21:                       <ScrollViewer中X:名称= “的ScrollViewer”
  22:                               TabNavigation = “{TemplateBinding TabNavigation}”
  23:                               HorizontalScrollMode = 
  24:                               {TemplateBinding ScrollViewer.HorizontalScrollMode}“
  25:                               HorizontalScrollBarVisibility =
  26:                                 “{TemplateBinding
  27:                                 ScrollViewer.HorizontalScrollBarVisibility}“
  28:                               IsHorizontalScrollChainingEnabled =
  29:                                 “{TemplateBinding
  30:                                 ScrollViewer.IsHorizontalScrollChainingEnabled}“
  31:                               VerticalScrollMode = 
  32:                               {TemplateBinding ScrollViewer.VerticalScrollMode}“
  33:                               VerticalScrollBarVisibility =
  34:                                 “{TemplateBinding
  35:                                 ScrollViewer.VerticalScrollBarVisibility}“
  36:                               IsVerticalScrollChainingEnabled =
  37:                                 “{TemplateBinding
  38:                                 ScrollViewer.IsVerticalScrollChainingEnabled}“
  39:                               IsHorizontalRailEnabled = 
  40:                               {TemplateBinding ScrollViewer.IsHorizontalRailEnabled}“
  41:                               IsVerticalRailEnabled = 
  42:                               {TemplateBinding ScrollViewer.IsVerticalRailEnabled}“
  43:                               ZoomMode = “{TemplateBinding
  44:                               ScrollViewer.ZoomMode}“
  45:                               IsDeferredScrollingEnabled = 
  46:                               {TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}“
  47:                               BringIntoViewOnFocusChange = 
  48:                               {TemplateBinding ScrollViewer.BringIntoViewOnFocusChange}“>
  49:                           <StackPanel的方向= “横向” >
  50:                               <边框宽度= “60” 
  51:                               X:名称= “NewGroupPlaceHolderFirst” 
  52:                                       背景= “透明” 
  53:                                       填充= “{TemplateBinding填充}” 
  54:                                       能见度= “{结合AllowNewGroup,
  55:                                       转换器= {静态资源
  56:                                         VisibilityConverter},
  57:                                         的RelativeSource = {的RelativeSource TemplatedParent}}“/>
  58:                               <ItemsPresenter
  59:                                   标题= “{TemplateBinding头}” 
  60:                                   HeaderTemplate中= “{TemplateBinding HeaderTemplate中}”
  61:                                   HeaderTransitions = “{TemplateBinding HeaderTransitions}”
  62:                                   填充= “{TemplateBinding填充}” />
  63:                               <边框宽度= “60” 
  64:                               X:名称= “NewGroupPlaceHolderLast” 
  65:                                       背景= “透明” 
  66:                                       填充= “{TemplateBinding填充}” 
  67:                                       能见度= “{结合AllowNewGroup,
  68:                                       转换器= {静态资源
  69:                                         VisibilityConverter},
  70:                                         的RelativeSource = {的RelativeSource TemplatedParent}}“/>
  71:                           </ StackPanel中>
  72:                       </ ScrollViewer中>
  73:                   </边框>
  74:               </控件模板>
  75:           </Setter.Value>
  76:       </二传手>
  77:   </样式>

 

丰富GridViewEx功能

如上所示,我们已经实现了基本的拖拽操作,与Windows8的开始菜单类似的功能,接下来讨论如何实现以下功能:

  • 尺寸大小不定的内容项
  • 分组
  • 添加新组
  • 节省跨会话布局空间

大小不定的内容项

Windows8展示了不同大小的Tiles,但是目前GridView或GridViewEx还不支持此功能。因为GridView使用WrapGrid作为默认的ItemsPanel,WrapPanel只能创建一种布局,即所有的条目尺寸相同的。因此微软提供了VariableSizedWrapGrid,支持不同大小块的布局创建。

GridViewEx控件的优势在于能够使用VariableSizedWrapGrid,并且很好的支持拖放操作。为了使用VariableSizedWrapGrid并显示不同大小的内容项,必须实现以下功能:

将GridViewEx.ItemsPanel设置为VariableSizedWrapGrid

在GridView控件中重写GridView控件的预pareContainerForItemOverride方法。在该方法中,可以设置Item的RowSpan或ColumnSpan属性来识别内容项的大小。

即生成继承GridViewEx的新控件MyGridView。为什么需要扩展GridViewEx控件而不是重写GridViewEx的PrepareContainerForItemOverride方法?因为指定Item尺寸的逻辑必须放在数据模型中,而不是控件内部。

如想将某一项显示较大一点,需要在数据项中创建一个属性返回比1大的整型数值,来设置RowSpanhuoColumnSpan属性。

   1:   公共 项目
   2:   {
   3:       公共 INT标识{搞定; 组; }
   4:       公共 INT ItemSize {搞定; 组; }
   5:       / * * /
   6:   }

因此,当创建新的内容项,我们要指定ItemSize属性。如果值为1则表明常规尺寸,如果值为2则表明大尺寸,ColumnSpan属性则设置为2。

   1:   /// <摘要>
   2:   ///这个类设置为VariableSizedWrapGrid.ColumnSpanProperty控制GridViewItem,
   3:   ///让每一个项目都可以在VariableSizedWrapGrid不同尺寸。
   4:   /// </摘要>
   5:   公共  MyGridView:GridViewSamples.Controls.GridViewEx
   6:   {
   7:       //根据业务逻辑来设置ColumnSpan
   8:       //(也许有些GridViewSamples.Samples.Item或一组属性)
   9:       保护 覆盖 无效 PrepareContainerForItemOverride(
  10:                 Windows.UI.Xaml.DependencyObject元素,对象项)
  11:       {
  12:           尝试
  13:           {
  14:               GridViewSamples.Samples.Item它=项目 GridViewSamples.Samples.Item;
  15:               如果(!它= 
  16:               {
  17:                   element.SetValue(
  18:                     Windows.UI.Xaml.Controls.VariableSizedWrapGrid.ColumnSpanProperty,it.ItemSize);
  19:               }
  20:           }
  21:           
  22:           {
  23:               element.SetValue(Windows.UI.Xaml.Controls.VariableSizedWrapGrid.ColumnSpanProperty,1);
  24:           }
  25:           终于
  26:           {
  27:               基地 .PrepareContainerForItemOverride(元素,项目);
  28:           }
  29:       }
  30:   }

创建MyGridView实例,并绑定到数据集合。

   1:   <本地:MyGridView的AllowDrop = “真” CanReorderItems = “真” 
   2:             CanDragItems = “真” IsSwipeEnabled = “真”
   3:             ItemsSource的= “{结合}” 
   4:             ItemTemplate中= “{StaticResource的ItemTemplate中}” >
   5:       <GridView.ItemsPanel>
   6:           <ItemsPanelTemplate>
   7:               <VariableSizedWrapGrid ItemHeight = “160” 
   8:               ItemWidth = “160” />
   9:           </ ItemsPanelTemplate>
  10:       </GridView.ItemsPanel>
  11:       <GridView.ItemContainerStyle>
  12:           <样式的TargetType = “GridViewItem” >
  13:               <setter属性= “HorizontalContentAlignment” 
  14:               值= “拉伸” />
  15:               <setter属性= “VerticalContentAlignment” 
  16:               值= “拉伸” />
  17:           </样式>
  18:       </GridView.ItemContainerStyle>
  19:   </地方:MyGridView>

如上所示,我们将指定内容项的ItemSize属性设置为2,效果如图所示:

分组

使用GridViewEx控件,能够实现添加新分组和拖拽等功能,也是在App中最为常见的功能,实现分组必须完成以下设置:

  • 为GridView绑定CollectionViewSource,必须使用支持分组的数据源。CollectionViewSource可视为代理服务器。
  • 使用GroupStyle确定分组结果如何显示,GroupStyle包含头Tempate及面板,因此需要指定子项目的排序方式。

在GridViewEx中添加支持不同大小的内容项,逻辑代码:

   1:   <本地:MyGridView的AllowDrop = “真” CanReorderItems = “真” 
   2:             CanDragItems = “真” IsSwipeEnabled = “真”
   3:             ItemsSource的= “{结合}” 
   4:             ItemTemplate中= “{StaticResource的ItemTemplate中}” >
   5:       <GridView.ItemsPanel>
   6:           <ItemsPanelTemplate>
   7:               <VirtualizingStackPanel方向= “横向” />
   8:           </ ItemsPanelTemplate>
   9:       </GridView.ItemsPanel>
  10:       <GridView.GroupStyle>
  11:           <GroupStyle>
  12:               <GroupStyle.HeaderTemplate>
  13:                   <DataTemplate中>
  14:                       <网格背景= “浅灰色” 
  15:                       保证金= “0” >
  16:                           <TextBlock的前景= “黑” 
  17:                           保证金= “10” 
  18:                                     风格= “{StaticResource的
  19:                                     GroupHeaderTextStyle}“>
  20:                               <运行文本= “{绑定ID}” />
  21:                               <运行文本= “组” />
  22:                           </ TextBlock的>
  23:                       </格>
  24:                   </ DataTemplate中>
  25:               </GroupStyle.HeaderTemplate>
  26:   
  27:               <GroupStyle.ContainerStyle>
  28:                   <样式的TargetType = “GroupItem” >
  29:                       <setter属性= “BorderBrush” 
  30:                       值= “深灰” />
  31日:                       <setter属性= “了borderThickness” 
  32:                       值= “2” />
  33:                       <setter属性= “保证金” 
  34:                       值= “3.0” />
  35:                   </样式>
  36:               </GroupStyle.ContainerStyle>
  37:   
  38:               <GroupStyle.Panel>
  39:                   <ItemsPanelTemplate>
  40:                       <VariableSizedWrapGrid ItemHeight = “160” 
  41:                       ItemWidth = “160” />
  42:                   </ ItemsPanelTemplate>
  43:               </GroupStyle.Panel>
  44:           </ GroupStyle>
  45:       </GridView.GroupStyle>
  46:   
  47:       <GridView.ItemContainerStyle>
  48:           <样式的TargetType = “GridViewItem” >
  49:               <setter属性= “HorizontalContentAlignment” 
  50:               值= “拉伸” />
  51:               <setter属性= “VerticalContentAlignment” 
  52:               值= “拉伸” />
  53:           </样式>
  54:       </GridView.ItemContainerStyle>
  55:   </地方:MyGridView>

运行演示:

添加新分组

自定义的GridViewEx控件支持新分组的创建,因此需要设置AllowNewGroup为True。其次处理添加新分组的数据层,处理GridViewEx.BeforeDrop事件。

   1:   /// <摘要>
   2:   ///创建新的CollectionViewSource和更新页面的DataContext。
   3:   /// </摘要>
   4:   私人 无效 UpdateDataContext()
   5:   {
   6:       CollectionViewSource源=  CollectionViewSource();
   7:       source.Source = _groups;
   8:       source.ItemsPath = 的PropertyPath( “ 项目”);
   9:       source.IsSourceGrouped =  ;
  10:        .DataContext =来源;
  11:   }
  12:   //在数据源中创建新的组,
  13:   //如果最终用户拖动项目到新组的占位符
  14:   私人 无效 MyGridView_BeforeDrop(对象发件人,Controls.BeforeDropItemsEventArgs E)
  15:   {
  16:       如果(e.RequestCreateNewGroup)
  17:       {
  18:           //创建新组,并重新分配数据源
  19:           组组= Group.GetNewGroup();
  20:           如果(e.NewGroupIndex == 0)
  21:           {
  22:               _groups.Insert(0,基);
  23:           }
  24:           其它
  25:           {
  26:               _groups.Add(组);
  27:           }
  28:           UpdateDataContext();
  29:       }
  30:   }

也可以使用拖放事件删除空分组

   1:   //删除空组(除了最后一个)
   2:   私人 无效 MyGridView_Drop(对象发件人,DragEventArgs E)
   3:   {
   4:       布尔 needReset = 虚假的 ;
   5:       诠释我= _groups.Count - 1; I> = 0;我- )
   6:       {
   7:           如果(_groups [I] .Items.Count == 0 && _groups.Count> 1)
   8:           {
   9:               _groups.RemoveAt(ⅰ);
  10:               needReset =  ;
  11:           }
  12:       }
  13:       如果(needReset)
  14:       {
  15:           UpdateDataContext();
  16:       }
  17:   }

节省布局空间

Windows8支持挂起或终止功能,为了提供更好的用户体验,我们继续改善此前实现的功能,当用户离开当前页面,将当前的布局暂存。在本示例中,我们使用JSON字符串简化数据序列化。根据已有的数据、数据的大小及需求,以其他格式来保存数据。我们主要将“业务对象集合”保存。

为了节省布局空间重写。LayoutAwarePage方法:

   1:   /// <摘要>
   2:   ///填充导航过程中传递的内容页面。任何保存状态也
   3:   ///从以前的会话再造一个页面时提供。
   4:   /// </摘要>
   5:   /// <param name =“navigationParameter”>传递参数值
   6:   /// <见CREF =“Frame.Navigate(类型,
   7:   ///对象)“/>时,最初请求该页面。
   8:   /// </ param>
   9:   /// <param name =“pageState”
  10:   ///>状态的字典中较早通过此页面保存下来
  11:   ///会话。这将是空的第一次网页被访问。</ param>
  12:   保护 覆盖 无效 LoadState的(对象navigationParameter,
  13:       词典<字符串,对象> pageState)
  14:   {
  15:       基地 .LoadState(navigationParameter,pageState);
  16:       如果!(pageState =  && pageState.Count> 0
  17:       && pageState.ContainsKey( “ 组”))
  18:       {
  19:           //恢复组和项目从以前序列状态
  20:           System.Runtime.Serialization.Json.DataContractJsonSerializer rootSer =
  21:            System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof运算(名单<集团>));
  22:           VAR流= 的MemoryStream(System.Text.Encoding.UTF8.GetBytes
  23:              (()pageState [ “组”));
  24:           _groups =(名单<集团>)rootSer.ReadObject(流);
  25:       }
  26:       其它
  27:       {
  28:           //如果我们在这里第一次,并且没有
  29:           //序列化的内容,填补从无到有组和项目
  30:           INT J = 1;Ĵ<= 12; J ++)
  31:           {
  32:               组组= Group.GetNewGroup();
  33:               诠释我= 1; I <= 7 + J%3;我++)
  34:               {
  35:                   group.Items.Add(项目()
  36:                   {
  37:                       编号= i,则
  38:                       的GroupId = group.Id
  39:                   });
  40:               }
  41:               _groups.Add(组);
  42:           }
  43:       }
  44:       UpdateDataContext();
  45:   }
  46:   
  47:   /// <摘要>
  48:   ///保持了与此页面的情况下,有关国家将暂停应用程序或
  49:   ///页被从引导高速缓冲存储器被丢弃。值必须符合系列化
  50:   的要求/// <见CREF =“SuspensionManager.SessionState”/>。
  51:   /// </摘要>
  52:   /// <param name =“pageState”>
  53:   ///空dictionary与序列化状态来填充</ param>。
  54:   保护 覆盖 无效即时存档(词典<字符串,对象> pageState)
  55:   {
  56:       //组和项目保存到JSON字符串,使
  57:       //有可能在以后还原页面状态
  58:       基地 .SaveState(pageState);
  59:       System.Runtime.Serialization.Json.DataContractJsonSerializer rootSer =
  60:            System.Runtime.Serialization.Json.DataContractJsonSerializer
  61:  typeof运算(名单<集团>));
  62:       VAR流= 的MemoryStream();
  63:       rootSer.WriteObject(流_groups);
  64:       字符串 STR = System.Text.Encoding.UTF8.GetString(stream.ToArray()
  65:               0,(INT)stream.Length);
  66:       pageState.Add( “ 组”,STR);
  67:   }
  68:   
  69:   /// <摘要>
  70:   ///调用时,这个网页是关于要显示在一个框架。
  71:   /// </摘要>
  72:   /// <param name =“E”>事件数据描述
  73:   ///这个页面是如何得出的。参数
  74:   ///属性通常用于配置页</ param>的。
  75:   保护 覆盖 无效的OnNavigatedTo(NavigationEventArgs E)
  76:   {
  77:       //恢复页面的状态
  78:       VAR frameState =
  79:       GridViewSamples.Common.SuspensionManager.SessionStateForFrame( .Frame);
  80:       如果(frameState.ContainsKey(“TilePageData” ))
  81:       {
  82:            .LoadState(e.Parameter,
  83:          (词典<字符串,对象>)frameState [ “TilePageData” ]);
  84:       }
  85:       其它
  86:       {
  87:            .LoadState(e.Parameter,);
  88:       }
  89:   }
  90:   
  91:   保护 覆盖 无效 OnNavigatedFrom(NavigationEventArgs E)
  92:   {
  93:       //保存页面的状态为“TilePageData”键
  94:       VAR frameState =
  95:       GridViewSamples.Common.SuspensionManager.SessionStateForFrame( .Frame);
  96:       VAR pageState = 词典<字符串,对象>();
  97:        .SaveState(pageState);
  98:       frameState [ “TilePageData” ] = pageState;
  99:   }

总结

GridViewEx控件丰富了GirdView控件功能,改进了基础功能,提升用户体验。到此已经实现了GridView项与Windows8开始菜单具有的相同用户体验,如果你想了解如何在Windows10平台下开发UWP引用,请持续关注下篇文章:如何在Windows10中开发UWP应用

除了 GirdView以外,具备触摸和键盘导航操作的自动或手动平铺布局的控件还有ComponentOne的TileControl为WinForms ,它不但提供自适应Windows8的样式布局,还具有类似Windows8风格的交互体验和灵活便捷的定制能力。

原文链接:http://www.codeproject.com/Articles/536519/Extending-GridView-with-Drag-and-Drop-for-Grouping

0 1
原创粉丝点击