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

简介: 原文:重新想象 Windows 8 Store Apps (13) - 控件之 SemanticZoom[源码下载] 重新想象 Windows 8 Store Apps (13) - 控件之 SemanticZoom 作者:webabcd介绍重新想象 Windows 8 Store Apps ...
原文: 重新想象 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 = 0;

        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
[源码下载]

目录
相关文章
|
Linux C++ Windows
【Azure 应用服务】Azure App Service(Windows)环境中如何让.NET应用调用SAP NetWeaver RFC函数
【Azure 应用服务】Azure App Service(Windows)环境中如何让.NET应用调用SAP NetWeaver RFC函数
457 0
【Azure 应用服务】Azure App Service(Windows)环境中如何让.NET应用调用SAP NetWeaver RFC函数
|
C# Windows
【Azure App Service】在App Service for Windows上验证能占用的内存最大值
根据以上测验,当使用App Service内存没有达到预期的值,且应用异常日志出现OutOfMemory时,就需要检查Platform的设置是否位64bit。
407 11
|
Java 应用服务中间件 开发工具
[App Service for Windows]通过 KUDU 查看 Tomcat 配置信息
[App Service for Windows]通过 KUDU 查看 Tomcat 配置信息
318 2
|
Java 应用服务中间件 Windows
【App Service for Windows】为 App Service 配置自定义 Tomcat 环境
【App Service for Windows】为 App Service 配置自定义 Tomcat 环境
283 2
|
PHP Windows
【Azure App Service for Windows】 PHP应用出现500 : The page cannot be displayed because an internal server error has occurred. 错误
【Azure App Service for Windows】 PHP应用出现500 : The page cannot be displayed because an internal server error has occurred. 错误
418 1
|
PHP 开发工具 git
【Azure 应用服务】在 App Service for Windows 中自定义 PHP 版本的方法
【Azure 应用服务】在 App Service for Windows 中自定义 PHP 版本的方法
381 1
|
网络安全 API 数据安全/隐私保护
【Azure App Service】.NET代码实验App Service应用中获取TLS/SSL 证书 (App Service Windows)
【Azure App Service】.NET代码实验App Service应用中获取TLS/SSL 证书 (App Service Windows)
316 0
|
Shell PHP Windows
【Azure App Service】Web Job 报错 UNC paths are not supported. Defaulting to Windows directory.
【Azure App Service】Web Job 报错 UNC paths are not supported. Defaulting to Windows directory.
348 0
|
存储 Linux Windows
【应用服务 App Service】App Service For Windows 如何挂载Storage Account File Share 示例
【应用服务 App Service】App Service For Windows 如何挂载Storage Account File Share 示例
249 0
|
应用服务中间件 nginx Windows
【Azure 应用服务】在App Service for Windows中实现反向代理
【Azure 应用服务】在App Service for Windows中实现反向代理
349 0

热门文章

最新文章