zoukankan      html  css  js  c++  java
  • 重新想象 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
    [源码下载]

  • 相关阅读:
    关于Date相关函数在火狐Firefox和谷歌Chrome下的不同
    一键部署 LNMP 建站环境
    Python 返回值、方法和函数的区别
    Python中万物皆对象?的理解
    Python 实用小工具 练习(2)
    Chrome浏览器F12开发者工具使用教程博客汇总
    觅风易语言[21-24、30]
    觅风易语言[1-10]
    觅风易语言[11-20]
    Python Byte类型(API系列)
  • 原文地址:https://www.cnblogs.com/webabcd/p/2972537.html
Copyright © 2011-2022 走看看