原文:重新想象 Windows 8 Store Apps (12) - 控件之 GridView 特性: 拖动项, 项尺寸可变, 分组显示

[源码下载]

重新想象 Windows 8 Store Apps (12) - 控件之 GridView 特性: 拖动项, 项尺寸可变, 分组显示

作者:webabcd

介绍
重新想象 Windows 8 Store Apps 之 GridView

  • 拖动项 - 在 GridView 内拖动 item 以对 item 排序, 拖动 item 到 GridView 外的指定位置以删除 item
  • 项尺寸可变 - 指定 GirdView 中每个 item 所占尺寸
  • 分组显示 - 分组显示集合数据

示例
1、演示如何在 GridView 内拖动 item 以对 item 排序,以及如何拖动 item 到 GridView 外的指定位置以删除 item
GridView/DragItem.xaml

<Page
x:Class="XamlDemo.Controls.GridView.DragItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XamlDemo.Controls.GridView"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Page.Resources>
<DataTemplate x:Key="ItemTemplate">
<StackPanel Orientation="Vertical">
<TextBlock TextWrapping="Wrap" FontSize="14.667" Text="{Binding Name}" HorizontalAlignment="Left" />
<TextBlock TextWrapping="Wrap" FontSize="14.667" Text="{Binding Age}" HorizontalAlignment="Left"/>
</StackPanel>
</DataTemplate>
<Style x:Key="ItemContainerStyle" TargetType="GridViewItem">
<Setter Property="Width" Value="292" />
<Setter Property="Height" Value="80" />
<!--
即使将 Margin 设置为“0”,也无法去掉 item 之间的 margin
如果想要去掉 item 之间的 margin,请将此 Margin 属性设置为“-4”
-->
<Setter Property="Margin" Value="0" />
<Setter Property="Background" Value="Blue" />
</Style>
<ItemsPanelTemplate x:Key="ItemsPanel">
<!--
注:WrapGrid 继承了 VirtualizingPanel,而 VariableSizedWrapGrid 并未继承 VirtualizingPanel
-->
<WrapGrid MaximumRowsOrColumns="3" Orientation="Vertical" VerticalChildrenAlignment="Top" HorizontalChildrenAlignment="Left" />
</ItemsPanelTemplate>
</Page.Resources> <Grid Background="Transparent">
<StackPanel Margin="120 0 0 0"> <TextBlock Name="lblMsg" FontSize="14.667" Text="通过拖动 GirdView 中的 Item 进行排序" /> <GridView x:Name="gridView" VerticalAlignment="Top" Margin="0 10 10 0" BorderThickness="1" BorderBrush="Red" Background="LightBlue"
ItemTemplate="{StaticResource ItemTemplate}"
ItemContainerStyle="{StaticResource ItemContainerStyle}"
ItemsPanel="{StaticResource ItemsPanel}"
IsSwipeEnabled="True" IsItemClickEnabled="True"
CanDragItems="True" CanReorderItems="True" AllowDrop="True"
DragItemsStarting="gridView_DragItemsStarting_1" /> <!--拖动 item 到此处以删除 item-->
<Grid Name="gridDelete" Margin="0 10 0 0" AllowDrop="True" Drop="gridDelete_Drop_1" DragEnter="gridDelete_DragEnter_1" DragLeave="gridDelete_DragLeave_1" DragOver="gridDelete_DragOver_1">
<Rectangle Width="300" Height="100" StrokeThickness="1" StrokeDashArray="2" Stroke="Red" Fill="Blue" />
<TextBlock FontSize="26.667" Text="拖动到此处以删除" TextAlignment="Center" VerticalAlignment="Center" />
</Grid> </StackPanel>
</Grid>
</Page>

GridView/DragItem.xaml.cs

/*
* 演示如何在 GridView 内拖动 item 以对 item 排序,以及如何拖动 item 到 GridView 外的指定位置以删除 item
*
* GridView - 网格控件
* CanDragItems - item 是否可被拖动
* CanReorderItems - 是否可通过拖动 item 来排序
* AllowDrop - 是否可在 GridView 中 drop
* DragItemsStarting - item 开始被拖动时所触发的事件(事件参数 DragItemsStartingEventArgs)
*
* DragItemsStartingEventArgs
* Items - 被拖动的 items 集合
* Cancel - 是否取消拖动操作
* Data - 一个 DataPackage 类型的对象,用于传递数据(与 DataPackage 在剪切板和 Share Contract 中的作用一样)
*
*
* 注:
* drag-drop 间传递数据,clipboard 间传递数据,Share Contract 间传递数据,以及其他场景的数据传递均可通过 DataPackage 类型的对象来完成
* 本例没有通过 DataPackage 来传递数据(太麻烦),而是通过一个私有字段来传递数据(比较简单)
*/ using System.Collections.ObjectModel;
using Windows.UI.Xaml.Controls;
using System.Linq;
using XamlDemo.Model;
using Windows.UI.Xaml;
using System.Diagnostics; namespace XamlDemo.Controls.GridView
{
public sealed partial class DragItem : Page
{
// 数据源
private ObservableCollection<Employee> _dataSource;
// 拖动中的 Employee 对象
private Employee _draggingEmployee; public DragItem()
{
this.InitializeComponent(); // 绑定数据
_dataSource = new ObservableCollection<Employee>(TestData.GetEmployees());
gridView.ItemsSource = _dataSource; // GridView 中的 items 发生变化时触发的事件
gridView.ItemContainerGenerator.ItemsChanged += ItemContainerGenerator_ItemsChanged;
} void ItemContainerGenerator_ItemsChanged(object sender, Windows.UI.Xaml.Controls.Primitives.ItemsChangedEventArgs e)
{
if (e.OldPosition.Index > -)
{
// 在 GridView 中 drop 了 item,且排序发生了变化 var oldIndex = _dataSource.IndexOf(_draggingEmployee); // 被拖动的 Employee 对象的原位置
var newIndex = e.Position.Index + e.Position.Offset; // 被拖动的 Employee 对象的新位置 // 修改数据源
_dataSource.Move(oldIndex, newIndex); _draggingEmployee = null;
} } // GridView 中的 item 开始被拖动时
private void gridView_DragItemsStarting_1(object sender, DragItemsStartingEventArgs e)
{
_draggingEmployee = e.Items.First() as Employee;
} // GridView 中的 item 被 drop 到了指定的位置后
private void gridDelete_Drop_1(object sender, DragEventArgs e)
{
// 从数据源中删除指定的 Employee 对象
_dataSource.Remove(_draggingEmployee);
_draggingEmployee = null; // 在 gridDelete 放下了拖动项
Debug.WriteLine("Drop");
} private void gridDelete_DragEnter_1(object sender, DragEventArgs e)
{
// 拖动项被拖进 gridDelete 了
Debug.WriteLine("DragEnter");
} private void gridDelete_DragLeave_1(object sender, DragEventArgs e)
{
// 拖动项被拖出 gridDelete 了
Debug.WriteLine("DragLeave");
} private void gridDelete_DragOver_1(object sender, DragEventArgs e)
{
// 拖动项在 gridDelete 上面拖动着
Debug.WriteLine("DragOver");
}
}
}

2、演示如何指定 GirdView 中每个 item 所占尺寸
GridView/ColorModel.cs

using Windows.UI.Xaml.Media;

namespace XamlDemo.Controls.GridView
{
/// <summary>
/// 用于绑定到 VariableSized.xaml 中的 GridView 的数据实体模型
/// </summary>
class ColorModel
{
public string ColorName { get; set; }
public SolidColorBrush ColorValue { get; set; } // 此对象所占的网格的列合并数
public int ColSpan { get; set; }
// 此对象所占的网格的行合并数
public int RowSpan { get; set; }
}
}

GridView/MyGridView.cs

/*
* 此控件可以指定 GridView 的每个 item 所占网格的列合并数和行合并数
*/ using System;
using System.Diagnostics; namespace XamlDemo.Controls.GridView
{
public class MyGridView : Windows.UI.Xaml.Controls.GridView
{
protected override void PrepareContainerForItemOverride(Windows.UI.Xaml.DependencyObject element, object item)
{
try
{
// 指定 VariableSizedWrapGrid 的 ColumnSpan 和 RowSpan dynamic dynamicItem = item;
element.SetValue(Windows.UI.Xaml.Controls.VariableSizedWrapGrid.ColumnSpanProperty, dynamicItem.ColSpan);
element.SetValue(Windows.UI.Xaml.Controls.VariableSizedWrapGrid.RowSpanProperty, dynamicItem.RowSpan);
}
catch(Exception ex)
{
// 当有异常情况发生时(比如:item 没有 ColSpan 属性或 RowSpan 属性) Debug.WriteLine(ex.ToString()); element.SetValue(Windows.UI.Xaml.Controls.VariableSizedWrapGrid.ColumnSpanProperty, );
element.SetValue(Windows.UI.Xaml.Controls.VariableSizedWrapGrid.RowSpanProperty, );
}
finally
{
base.PrepareContainerForItemOverride(element, item);
}
}
}
}

GridView/VariableSized.xaml

<Page
x:Class="XamlDemo.Controls.GridView.VariableSized"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XamlDemo.Controls.GridView"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Page.Resources>
<DataTemplate x:Key="ItemTemplate">
<Grid Background="{Binding ColorValue}">
<Grid Background="Black" VerticalAlignment="Top" HorizontalAlignment="Stretch" Opacity="0.7">
<TextBlock Text="{Binding ColorName}" />
</Grid>
</Grid>
</DataTemplate>
<Style x:Key="ItemContainerStyle" TargetType="GridViewItem">
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<!--
即使将 Margin 设置为“0”,也无法去掉 item 之间的 margin
如果想要去掉 item 之间的 margin,请将此 Margin 属性设置为“-4”
-->
<Setter Property="Margin" Value="-4" />
</Style>
<ItemsPanelTemplate x:Key="ItemsPanel">
<!--
注:WrapGrid 继承了 VirtualizingPanel,而 VariableSizedWrapGrid 并未继承 VirtualizingPanel ItemWidth, ItemHeight - 每个网格的宽和高
ColumnSpan, RowSpan - item 所在网格的列合并数和行合并数,本例在后台指定了这两个属性,参见 MyGridView.cs
-->
<VariableSizedWrapGrid MaximumRowsOrColumns="4" Orientation="Vertical" ItemWidth="100" ItemHeight="100" Height="400" />
</ItemsPanelTemplate> </Page.Resources> <Grid Background="Transparent">
<StackPanel Margin="120 0 0 0"> <!--
使用 MyGridView 控件,其重写了 GridView 的 PrepareContainerForItemOverride() 方法,详见 MyGridView.cs
-->
<local:MyGridView x:Name="gridView" Height="400" VerticalAlignment="Top" Margin="0 10 10 0" Background="Yellow"
ItemTemplate="{StaticResource ItemTemplate}"
ItemContainerStyle="{StaticResource ItemContainerStyle}"
ItemsPanel="{StaticResource ItemsPanel}"
IsItemClickEnabled="False" IsSwipeEnabled="False" SelectionMode="None"
ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Auto">
</local:MyGridView> </StackPanel>
</Grid>
</Page>

GridView/VariableSized.xaml.cs

/*
* 演示如何指定 GirdView 中每个 item 所占尺寸
* GridView 是一个网格控件,这里所谓的每个 item 所占尺寸,其本质上就是 item 所在网格的列合并数和行合并数
*
* 要实现此需求的话:
* 1、必须使用 VariableSizedWrapGrid,具体见 VariableSized.xaml
* 2、需要重写 GridView 的 PrepareContainerForItemOverride() 方法,具体见 MyGridView.cs
*/ using System.Reflection;
using System.Linq;
using System.Collections.Generic;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using System;
using Windows.UI; namespace XamlDemo.Controls.GridView
{
public sealed partial class VariableSized : Page
{
public VariableSized()
{
this.InitializeComponent(); BindData();
} private void BindData()
{
Random random = new Random(); // 获取 Windows.UI.Colors 的全部数据
List<ColorModel> colors = typeof(Colors) // typeof 在 System.Reflection 命名空间下
.GetRuntimeProperties()
.Select(c => new ColorModel
{
ColorName = c.Name,
ColorValue = new SolidColorBrush((Color)c.GetValue(null)),
ColSpan = random.Next(, ), // 此对象所占网格的列合并数
RowSpan = random.Next(, ) // 此对象所占网格的行合并数
})
.ToList(); // 绑定数据
gridView.ItemsSource = colors;
}
}
}

3、演示如何分组显示集合数据(关于分组的示例会和之后的 SemanticZoom 一起写)
GridView/Group.xaml

<Page
x:Class="XamlDemo.Controls.GridView.Group"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XamlDemo.Controls.GridView"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Grid Background="Transparent">
<StackPanel Margin="120 0 0 0"> <TextBlock Name="lblMsg" FontSize="14.667">
<Run>关于 GridView 的分组显示请参见本 app 的索引页 Index.xaml 和 Index.xaml.cs</Run>
<LineBreak />
<Run>分组的功能来源于 ItemsControl(GridView, ListView, FlipView, ListBox 等均继承了 ItemsControl)</Run>
</TextBlock> </StackPanel>
</Grid>
</Page>

OK
[源码下载]

重新想象 Windows 8 Store Apps (12) - 控件之 GridView 特性: 拖动项, 项尺寸可变, 分组显示的更多相关文章

  1. 重新想象 Windows 8 Store Apps (10) - 控件之 ScrollViewer 特性: Chaining, Rail, Inertia, Snap, Zoom

    原文:重新想象 Windows 8 Store Apps (10) - 控件之 ScrollViewer 特性: Chaining, Rail, Inertia, Snap, Zoom [源码下载] ...

  2. 重新想象 Windows 8 Store Apps (15) - 控件 UI: 字体继承, Style, ControlTemplate, SystemResource, VisualState, VisualStateManager

    原文:重新想象 Windows 8 Store Apps (15) - 控件 UI: 字体继承, Style, ControlTemplate, SystemResource, VisualState ...

  3. 重新想象 Windows 8 Store Apps (17) - 控件基础: Measure, Arrange, GeneralTransform, VisualTree

    原文:重新想象 Windows 8 Store Apps (17) - 控件基础: Measure, Arrange, GeneralTransform, VisualTree [源码下载] 重新想象 ...

  4. 重新想象 Windows 8 Store Apps (16) - 控件基础: 依赖属性, 附加属性, 控件的继承关系, 路由事件和命中测试

    原文:重新想象 Windows 8 Store Apps (16) - 控件基础: 依赖属性, 附加属性, 控件的继承关系, 路由事件和命中测试 [源码下载] 重新想象 Windows 8 Store ...

  5. 重新想象 Windows 8 Store Apps (14) - 控件 UI: RenderTransform, Projection, Clip, UseLayoutRounding

    原文:重新想象 Windows 8 Store Apps (14) - 控件 UI: RenderTransform, Projection, Clip, UseLayoutRounding [源码下 ...

  6. 重新想象 Windows 8 Store Apps (13) - 控件之 SemanticZoom

    原文:重新想象 Windows 8 Store Apps (13) - 控件之 SemanticZoom [源码下载] 重新想象 Windows 8 Store Apps (13) - 控件之 Sem ...

  7. 重新想象 Windows 8 Store Apps (11) - 控件之 ListView 和 GridView

    原文:重新想象 Windows 8 Store Apps (11) - 控件之 ListView 和 GridView [源码下载] 重新想象 Windows 8 Store Apps (11) - ...

  8. 重新想象 Windows 8 Store Apps (9) - 控件之 ScrollViewer 基础

    原文:重新想象 Windows 8 Store Apps (9) - 控件之 ScrollViewer 基础 [源码下载] 重新想象 Windows 8 Store Apps (9) - 控件之 Sc ...

  9. 重新想象 Windows 8 Store Apps (7) - 控件之布局控件: Canvas, Grid, StackPanel, VirtualizingStackPanel, WrapGrid, VariableSizedWrapGrid

    原文:重新想象 Windows 8 Store Apps (7) - 控件之布局控件: Canvas, Grid, StackPanel, VirtualizingStackPanel, WrapGr ...

随机推荐

  1. roll pitch yaw 的分别

    原文地址:http://blog.sina.com.cn/s/blog_452706120100scwu.html yaw,pitch,roll这三个旋转的确切意思.如果有一个人站在(0,0,0)点, ...

  2. 如何去掉List中的重复内容

    1.通过循环进行删除 public static void removeDuplicate(List list) { ; i < list.size() - ; i ++ ) { ; j > ...

  3. HDU 1007 近期点对

    分治法求近期点对 递归将点不断分成小组.计算最短距离.此时的最短距离不过两点都属两块的某一块(这里的切割点是mid点). 还须要考虑两点分属两块的情况. 这时对于选点则把范围缩小到了以mid为中心. ...

  4. [每日一题] 11gOCP 1z0-052 :2013-09-5 runInstaller oracle of no swap

    转载请注明出处:http://blog.csdn.net/guoyjoe/article/details/11186995 正确答案:A 我们先来看下面这张截图,这是我在安装Oracle 11.2.0 ...

  5. JMS学习(三)ActiveMQ Message Persistence(转)

    1,JMS规范支持两种类型的消息传递:persistent and non-persistent.ActiveMQ在支持这两种类型的传递方式时,还支持消息的恢复.中间状态的消息(message are ...

  6. 移动App測试实战:顶级互联网企业软件測试和质量提升最佳实践

    这篇是计算机类的优质预售推荐>>>><移动App測试实战:顶级互联网企业软件測试和质量提升最佳实践> 国内顶级互联网公司測试实战经验总结.阿里.腾讯.京东.携程.百 ...

  7. hdu2066一个人的旅行(dijkstra)

    Problem Description 虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,^0^),很多事,还能丰 ...

  8. hdu4908(中位数)

    传送门:BestCoder Sequence 题意:给一个序列,里面是1-N的排列,给出m,问以m为中位数的奇数长度的序列个数. 分析:先找出m的位置,再记录左边比m大的状态,记录右边比m大的状态,使 ...

  9. 联系我们_鲲鹏Web数据抓取 - 专业Web数据采集服务提供者

    联系我们_鲲鹏Web数据抓取 - 专业Web数据采集服务提供者 首页 > 联系我们 我们的联系方式如下: 029 - 82542052(陕西 西安) 13389148466 或 13571845 ...

  10. 纸板上的虚拟现实和代码中的Cardboard

    虚拟现实技术 未来视角? Google Cardboard试玩与比較 阅读下面文字请请先戳 戳我戳我 2014年的Google I/O大会,一向以Geek自称的Google拿出了一个叫做Cardboa ...