原文:重新想象 Windows 8 Store Apps (13) - 控件之 SemanticZoom

[源码下载]

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

作者:webabcd

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

  • 演示 SemanticZoom 的应用
  • 通过 ISemanticZoomInformation 接口实现自定义 SemanticZoom 的 View

示例
1、演示 SemanticZoom 的应用
Index.xaml

<Page
x:Class="XamlDemo.Index"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XamlDemo"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Grid Background="Transparent"> <SemanticZoom x:Name="semanticZoom" HorizontalAlignment="Left">
<!--
放大后的视图,详细数据
-->
<SemanticZoom.ZoomedInView>
<GridView x:Name="gridViewDetails" SelectionMode="None" IsSwipeEnabled="false" Padding="120 0 0 0"> <!--分组后,details 的数据模板-->
<GridView.ItemTemplate>
<DataTemplate>
<Grid Background="#022a56" Width="200" Height="65" Tapped="Grid_Tapped_1" Tag="{Binding}">
<TextBlock TextWrapping="Wrap" FontSize="14.667" Foreground="#ffffff" Padding="5 0"
HorizontalAlignment="Left" VerticalAlignment="Center"
Text="{Binding Title}"/>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
<!--分组的样式-->
<GridView.GroupStyle>
<GroupStyle>
<!--分组后,header 的数据模板-->
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}" FontSize="26.67" Height="30" Margin="0 0 0 20" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
<!--分组后,每组数据(包括 header 和 details)的样式-->
<GroupStyle.ContainerStyle>
<Style TargetType="GroupItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GroupItem">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Margin="{TemplateBinding Padding}"/>
<!--
每组数据的 details 数据源来自 ICollectionViewGroup.GroupItems
-->
<ItemsControl x:Name="ItemsControl" ItemsSource="{Binding GroupItems}" Grid.Row="1"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
<!--分组后,每组数据(包括 header 和 details)的 panel-->
<GroupStyle.Panel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid Orientation="Vertical" Margin="0 0 50 0" ItemHeight="75" Loaded="VariableSizedWrapGrid_Loaded_1" />
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</GridView.GroupStyle>
<!--整体数据(一组数据算一个元素)的 panel-->
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
</SemanticZoom.ZoomedInView> <!--
缩小后的视图,概述数据
-->
<SemanticZoom.ZoomedOutView>
<GridView Name="gridViewSummary" HorizontalAlignment="Left" Padding="120 0 0 0">
<GridView.ItemTemplate>
<DataTemplate>
<Grid Background="#022a56" Width="100" Height="100">
<!--
每组数据的 header 数据源来自 ICollectionViewGroup.Group
-->
<TextBlock Text="{Binding Group.Title}" Foreground="#ffffff" Opacity="0.9" FontSize="14.667" Margin="5" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap" />
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid MaximumRowsOrColumns="8" HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="Margin" Value="5 5 5 30" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
</Style>
</GridView.ItemContainerStyle>
</GridView>
</SemanticZoom.ZoomedOutView>
</SemanticZoom>
</Grid>
</Page>

Index.xaml.cs

/*
* 本页为此 app 的导航页,同时用于演示:
* 1、ItemsControl 控件如何分组
* 2、SemanticZoom 控件的应用
*
*
* SemanticZoom - 用于关联两个有语义关系的视图
* ZoomedInView - 放大后的视图,详细数据
* ZoomedOutView - 缩小后的视图,概述数据
* IsZoomedInViewActive - ZoomedInView 是否为当前正在显示的视图
* CanChangeViews - 是否可在两个视图间切换
* IsZoomOutButtonEnabled - 是否显示用于切换视图的按钮
* ToggleActiveView() - 切换视图
* ViewChangeStarted - 视图开始切换时触发的事件
* ViewChangeCompleted - 视图切换完成时触发的事件
*
*
* ItemsControl - 一个用于呈现集合数据的控件(GridView, ListView, FlipView, ListBox 等均直接或间接地继承了 ItemsControl)
* ItemsControl 控件提供了分组功能
*
* CollectionViewSource - 对集合数据启用分组支持
* Source - 数据源
* View - 获取视图对象,返回一个实现了 ICollectionView 接口的对象
* IsSourceGrouped - 数据源是否是一个被分组的数据
* ItemsPath - 数据源中,子数据集合的属性名称
*
* ICollectionView - 支持数据分组
* CollectionGroups - 组数据集合
*/ using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Navigation;
using XamlDemo.Common; namespace XamlDemo
{
public sealed partial class Index : Page
{
// 本页所用到的 GridView 的水平方向上的滚动值
private double _scrollViewerHorizontalOffset = ; public Index()
{
this.InitializeComponent(); XElement root = XElement.Load("SiteMap.xml");
var items = LoadData(root); // 构造数据源
CollectionViewSource groupedNavigationData = new CollectionViewSource();
groupedNavigationData.IsSourceGrouped = true;
groupedNavigationData.Source = items;
groupedNavigationData.ItemsPath = new PropertyPath("Items"); // 绑定数据
gridViewDetails.ItemsSource = groupedNavigationData.View; // 全部数据
gridViewSummary.ItemsSource = groupedNavigationData.View.CollectionGroups; // 关联的组数据集合 // 必须缓存此页
this.NavigationCacheMode = NavigationCacheMode.Required; gridViewDetails.Loaded += gridViewDetails_Loaded;
} // 导航到其它页之前,保存本页所用到的 GridView 的水平方向上的滚动值
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
var scrollViewer = Helper.GetVisualChild<ScrollViewer>(gridViewDetails);
_scrollViewerHorizontalOffset = scrollViewer.HorizontalOffset;
} // GridView 加载之后,指定其水平方向上的滚动值
void gridViewDetails_Loaded(object sender, RoutedEventArgs e)
{
var scrollViewer = Helper.GetVisualChild<ScrollViewer>(gridViewDetails);
scrollViewer.ScrollToHorizontalOffset(_scrollViewerHorizontalOffset);
} // 获取数据
private List<NavigationModel> LoadData(XElement root)
{
if (root == null)
return null; var items = from n in root.Elements("node")
select new NavigationModel
{
Title = (string)n.Attribute("title"),
Url = (string)n.Attribute("url"),
Items = LoadData(n)
}; return items.ToList();
} // 导航到指定的 Demo 页
private void Grid_Tapped_1(object sender, TappedRoutedEventArgs e)
{
var model = (NavigationModel)(sender as Grid).Tag; MainPage.Current.SubTitle = model.Title;
MainPage.Current.Container.Navigate(Type.GetType(model.Url));
} // 根据屏幕的 height 调整 VariableSizedWrapGrid 的 MaximumRowsOrColumns
// 本例会自动 wrap ,所以不需要以下逻辑,在需要的场景下可以用之
private void VariableSizedWrapGrid_Loaded_1(object sender, RoutedEventArgs e)
{
/*
var screenHeight = Window.Current.Bounds.Height; // CoreWindow.GetForCurrentThread().Bounds.Height var vswg = sender as VariableSizedWrapGrid;
vswg.MaximumRowsOrColumns = (int)((screenHeight - 200) / 75);
*/
} class NavigationModel
{
public string Title { get; set; }
public string Url { get; set; }
public List<NavigationModel> Items { get; set; }
}
}
}

2、演示如何自定义 SemanticZoom 视图
SemanticZoom/MyFlipView.cs

/*
* 开发一个实现了 ISemanticZoomInformation 接口的自定义 FlipView
*/ using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data; namespace XamlDemo.Controls.SemanticZoom
{
public class MyFlipView : FlipView, ISemanticZoomInformation
{
public MyFlipView()
: base()
{ } public void CompleteViewChange() { } public void CompleteViewChangeFrom(SemanticZoomLocation source, SemanticZoomLocation destination) { } public void CompleteViewChangeTo(SemanticZoomLocation source, SemanticZoomLocation destination) { } public void InitializeViewChange() { } public bool IsActiveView { get; set; } public bool IsZoomedInView { get; set; } public Windows.UI.Xaml.Controls.SemanticZoom SemanticZoomOwner { get; set; } public void StartViewChangeFrom(SemanticZoomLocation source, SemanticZoomLocation destination) { } /// <summary>
/// ZoomedOutView -> ZoomedInView 时触发的事件
/// </summary>
/// <param name="source">在 ZoomedOutView 时被选中的数据</param>
/// <param name="destination">需要传递给 ZoomedInView 的数据</param>
public void StartViewChangeTo(SemanticZoomLocation source, SemanticZoomLocation destination)
{
/*
* 注:
* GridView 和 ListView 均实现了 ISemanticZoomInformation 接口
* 参见本 app 的关于 SemanticZoom 的 Demo,通过 CollectionViewSource 绑定数据即可使 SemanticZoom 中的两个视图进行有关联地切换
* 此时此处的 source.Item 便为一个 ICollectionViewGroup 类型的数据,其有两个属性:Group 和 GroupItems
*/ // 获取在 ZoomedOutView 中被选中的项,即被选中的父亲
NavigationModel model = source.Item as NavigationModel;
// 将此父亲的所有子数据传递给 ZoomedInView,接下来会执行 MakeVisible() 方法
destination.Item = model.Items;
} /// <summary>
/// 开始 ZoomedOutView -> ZoomedInView 之后,会调用此方法
/// 一般在此处重整 ZoomedInView 的数据源,或者滚动 ZoomedInView 中的内容到指定的项以对应 ZoomedOutView 中被选中的数据
/// </summary>
/// <param name="item">由 StartViewChangeTo() 方法传递给 ZoomedInView 的数据</param>
public void MakeVisible(SemanticZoomLocation item)
{
// 将 FlipView 的数据源指定为被选中的父亲的所有子数据
this.ItemsSource = item.Item;
}
}
}

SemanticZoom/CustomView.xaml

<Page
x:Class="XamlDemo.Controls.SemanticZoom.CustomView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XamlDemo.Controls.SemanticZoom"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Grid Background="Transparent">
<SemanticZoom x:Name="semanticZoom" IsZoomedInViewActive="False" Margin="120 0 0 0">
<!--
放大后的视图,详细数据
-->
<SemanticZoom.ZoomedInView>
<local:MyFlipView x:Name="flipView" Width="600" Height="300" HorizontalAlignment="Left">
<FlipView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}" FontSize="26.667" />
</DataTemplate>
</FlipView.ItemTemplate>
<FlipView.ItemContainerStyle>
<Style TargetType="FlipViewItem">
<Setter Property="Background" Value="Blue" />
</Style>
</FlipView.ItemContainerStyle>
</local:MyFlipView>
</SemanticZoom.ZoomedInView> <!--
缩小后的视图,概述数据
-->
<SemanticZoom.ZoomedOutView>
<GridView Name="gridView" HorizontalAlignment="Left">
<GridView.ItemTemplate>
<DataTemplate>
<Grid Background="#022a56" Width="100" Height="100">
<TextBlock Text="{Binding Title}" Foreground="#ffffff" Opacity="0.9" FontSize="14.667" Margin="5" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap" />
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid MaximumRowsOrColumns="8" HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="Margin" Value="5 5 5 30" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
</Style>
</GridView.ItemContainerStyle>
</GridView>
</SemanticZoom.ZoomedOutView>
</SemanticZoom>
</Grid>
</Page>

SemanticZoom/CustomView.xaml.cs

/*
* 演示如何自定义 SemanticZoom 视图
* 演示步骤:
* 1、在 ZoomedOutView 视图中的 GridView 中选中某一项
* 2、展开 ZoomedInView 视图后,其内的 FlipView 显示之前被选中项的所有子数据(需要开发一个实现了 ISemanticZoomInformation 接口的自定义 FlipView,参见 MyFlipView.cs)
*
* 注:
* GridView 和 ListView 均实现了 ISemanticZoomInformation 接口,所以可以在 SemanticZoom 的两个视图间有关联地切换
* 要让其它控件也实现类似的功能,就必须使其实现 ISemanticZoomInformation 接口
*/ using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Windows.UI.Xaml.Controls; namespace XamlDemo.Controls.SemanticZoom
{
public sealed partial class CustomView : Page
{
public CustomView()
{
this.InitializeComponent(); XElement root = XElement.Load("SiteMap.xml");
var items = LoadData(root); // 绑定数据
gridView.ItemsSource = items;
} // 获取数据
private List<NavigationModel> LoadData(XElement root)
{
if (root == null)
return null; var items = from n in root.Elements("node")
select new NavigationModel
{
Title = (string)n.Attribute("title"),
Url = (string)n.Attribute("url"),
Items = LoadData(n)
}; return items.ToList();
}
} public class NavigationModel
{
public string Title { get; set; }
public string Url { get; set; }
public List<NavigationModel> Items { get; set; }
}
}

OK
[源码下载]

重新想象 Windows 8 Store Apps (13) - 控件之 SemanticZoom的更多相关文章

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

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

  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 (16) - 控件基础: 依赖属性, 附加属性, 控件的继承关系, 路由事件和命中测试

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

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

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

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

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

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

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

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

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

  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. Delphi xe7并行编程快速入门(三篇)

    现在多数设备.计算机都有多个CPU单元,即使是手机也是多核的.但要在开发中使用多核的优势,却需要一些技巧,花费时间编写额外的代码.好了,现在可以使用Delphi做并行编程了. 在Delphi.C++ ...

  2. HDU 3911 Black And White 分段树 题解

    Problem Description There are a bunch of stones on the beach; Stone color is white or black. Little ...

  3. AdaBoost中利用Haar特征进行人脸识别算法分析与总结1——Haar特征与积分图

    原地址:http://blog.csdn.net/watkinsong/article/details/7631241 目前因为做人脸识别的一个小项目,用到了AdaBoost的人脸识别算法,因为在网上 ...

  4. 44个JAVA代码质量管理工具(转)

    1. CodePro AnalytixIt’s a great tool (Eclipse plugin) for improving software quality. It has the nex ...

  5. MSA2312 enclosure 闪断后

    故障描述:由于电源原因,导致整个扩展柜闪断,硬盘全部为leftover状态. 存储划分配置:之前满配的一套MSA2312,划分为4个vd,后面两个vd无影响,前面2个VD都是一半在1号柜子,一半在2号 ...

  6. nginx &amp; flup &amp; django &amp; python3.x @ window7配置备忘录

    最近考虑原Prism建筑(非职业.半专业人士认为C/S建筑)至B/S迁移,主要是由于部署问题,包括两个因素:已经做,虽然一键安装和部署的一个因素,心存顾虑,虽然我一再声明这是一个绿色软件.还有一个因素 ...

  7. 浅谈spring——spring MVC(十一)

    springMVC框架主要是围绕DispatcherServlet这个核心展开,它负责拦截请求并将其分派给相应的的处理器处理,然后将结果响应给用户.包括注解驱动控制器.请求及响应信息处理.视图解析.本 ...

  8. hdu4059 The Boss on Mars

    The Boss on Mars Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  9. hdu 2451 Simple Addition Expression(数位DP )成败在于细节

    亚洲区域赛的题,简单的数位DP题,注重细节. 任何细节都有可能导致wa,所以没有绝对的水题. 把握好细节,此题便A. #include<stdio.h> __int64 getans(__ ...

  10. [WPF]使用Pack URI路径訪问二进制资源

    一.路径格式定义 完整的URI定义为: pack://application,,,[/可选程序集名称;][可选版本;][目录名称/]文件名 缩略后的写法是: [目录名称/]文件名 二.在XAML代码中 ...