引言
相信大家对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