zoukankan      html  css  js  c++  java
  • 背水一战 Windows 10 (69)

    [源码下载]


    背水一战 Windows 10 (69) - 控件(控件基类): UIElement - Manipulate 手势处理, 路由事件的注册, 路由事件的冒泡, 命中测试的可见性



    作者:webabcd


    介绍
    背水一战 Windows 10 之 控件(控件基类 - UIElement)

    • Manipulate 手势处理
    • 路由事件的注册
    • 路由事件的冒泡
    • 命中测试的可见



    示例
    1、演示 Manipulate 手势处理
    Controls/BaseControl/UIElementDemo/ManipulateDemo.xaml

    <Page
        x:Class="Windows10.Controls.BaseControl.UIElementDemo.ManipulateDemo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:Windows10.Controls.BaseControl.UIElementDemo"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="Transparent">
            <Grid Margin="10 0 10 10">
    
                <TextBlock Name="lblMsg" Margin="5" />
    
                <Rectangle Name="rectangle" Height="200" Width="200" Fill="Orange" Margin="5" />
    
            </Grid>
        </Grid>
    </Page>

    Controls/BaseControl/UIElementDemo/ManipulateDemo.xaml.cs

    /*
     * UIElement - UIElement(继承自 DependencyObject, 请参见 /Controls/BaseControl/DependencyObjectDemo/)
     *     ManipulationModes - 需要监测的手势(Windows.UI.Xaml.Input.ManipulationModes 枚举)
     *         None - 禁用手势监测
     *         TranslateX, TranslateY - 位移手势
     *         TranslateRailsX, TranslateRailsY - 带有轨道的位移手势
     *         Rotate - 旋转手势
     *         Scale - 缩放手势
     *         TranslateInertia - 带有惯性的位移手势
     *         RotateInertia - 带有惯性的旋转手势
     *         ScaleInertia - 带有惯性的缩放手势
     *         All - 监测全部手势
     *     ManipulationStarting - 触控操作开始时触发的事件
     *     ManipulationStarted - 触控操作开始后触发的事件
     *     ManipulationInertiaStarting - 触控操作的惯性开始时触发的事件
     *     ManipulationCompleted - 触控操作结束后触发的事件
     *     ManipulationDelta - 触控值发生变化时触发的事件
     * 
     * ManipulationStartingRoutedEventArgs
     *     Container - 此 Manipulation 的容器
     *     Mode - 获取或设置 ManipulationModes
     *     Pivot - 获取或设置轴对象,ManipulationPivot 类型的数据
     *         Center - 旋转中心点
     *         Radius - 有效的旋转半径
     * 
     * ManipulationStartedRoutedEventArgs
     *     Container - 此 Manipulation 的容器
     *     Cumulative - 自操作开始后的累计变化量,返回 ManipulationDelta 类型的对象
     *     Position - 触摸点相对于 UIElement 的位置
     *     Complete() - 马上完成 Manipulation 而不发生惯性
     * 
     * ManipulationDeltaRoutedEventArgs
     *     Container - 此 Manipulation 的容器
     *     Cumulative - 自操作开始后的累计变化量,返回 ManipulationDelta 类型的对象
     *     Delta - 当前变化量,返回 ManipulationDelta 类型的对象
     *     Velocities - 当前变化的速率,返回 ManipulationVelocities 类型的对象
     *     IsInertial - 是否在惯性运动之中
     *     Position - 触摸点相对于 UIElement 的位置
     *     Complete() - 马上完成 Manipulation 而不发生惯性
     *     
     * ManipulationInertiaStartingRoutedEventArgs
     *     Container - 此 Manipulation 的容器
     *     Cumulative - 自操作开始后的累计变化量,返回 ManipulationDelta 类型的对象
     *     Delta - 当前变化量,返回 ManipulationDelta 类型的对象
     *     Velocities - 当前变化的速率,返回 ManipulationVelocities 类型的对象
     *     ExpansionBehavior - 惯性的缩放行为,获取或设置 InertiaExpansionBehavior 类型的对象
     *         DesiredDeceleration - 惯性运动时,缩放的减慢速率
     *         DesiredExpansion - 惯性结束后,缩放的值
     *     RotationBehavior - 惯性的旋转行为,获取或设置 InertiaRotationBehavior 类型的对象
     *         DesiredDeceleration - 惯性运动时,旋转的减慢速率
     *         DesiredRotation - 惯性结束后,旋转的度数
     *     TranslationBehavior - 惯性的位移行为,获取或设置 InertiaTranslationBehavior 类型的对象
     *         DesiredDeceleration - 惯性运动时,直线位移的减慢速率
     *         DesiredDisplacement - 惯性结束后,直线位移的的值
     *         
     * ManipulationCompletedRoutedEventArgs
     *     Container - 此 Manipulation 的容器
     *     Cumulative - 自操作开始后的累计变化量,返回 ManipulationDelta 类型的对象
     *     Velocities - 当前变化的速率,返回 ManipulationVelocities 类型的对象
     *     IsInertial - 结束前是否发生了惯性运动
     *     Position - 触摸点相对于 UIElement 的位置
     * ManipulationDelta - 变化量
     *     Expansion - 触摸点间距离的变化,单位 dip
     *     Scale - 触摸点间距离的变化,以一个百分比表示
     *     Rotation - 旋转角度的变化,以角度为单位
     *     Translation - 位移的变化,Point 类型的对象
     * ManipulationVelocities - 变化速率
     *     Angular - 旋转速度,单位:度/毫秒
     *     Expansion - 缩放速度,单位:dip/毫秒
     *     Linear - 直线位移速度,单位:Point/毫秒
     *     
     * 
     * 什么是 dip: device independent pixels(设备独立像素),不管屏大小和分辨率,把屏幕分成 480 * 320 个点,其中每一点代表 1 dip
     * Manipulate 是 UIElement 级别的手势操作;GestureRecognizer 是 app 级别的手势识别
     * 
     * 
     * 本例用于演示 UIElement 的 Manipulate 的应用(位移手势,缩放手势,旋转手势)
     * 
     * 
     * 注:关于 Manipulate Pointer Tap 的区别如下
     * 1、Manipulate 是最底层,Pointer 在中间,Tap 是最高层,所以会先走 Manipulate 事件,再走 Pointer 事件,最后走 Tap 事件
     * 2、如果高层的事件被触发,最相对于它的底层的事件也会被触发,反之则不一定
     * 3、使用原则是能在高层处理的事件尽量在高层处理(开发会简单些)
     */
    
    using System;
    using Windows.Foundation;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Input;
    using Windows.UI.Xaml.Media;
    
    namespace Windows10.Controls.BaseControl.UIElementDemo
    {
        public sealed partial class ManipulateDemo : Page
        {
            private TransformGroup _transformGroup;
            private CompositeTransform _compositeTransform;
            private MatrixTransform _previousTransform;
    
            public ManipulateDemo()
            {
                this.InitializeComponent();
    
                // 监测全部手势
                rectangle.ManipulationMode = ManipulationModes.All;
                // 仅监测旋转手势和缩放手势
                // rectangle.ManipulationMode = ManipulationModes.Rotate | ManipulationModes.Scale;
    
                _transformGroup = new TransformGroup();
                _compositeTransform = new CompositeTransform();
                _previousTransform = new MatrixTransform() { Matrix = Matrix.Identity };
    
                _transformGroup.Children.Add(_previousTransform);
                _transformGroup.Children.Add(_compositeTransform);
    
                rectangle.RenderTransform = _transformGroup;
    
                rectangle.ManipulationStarting += rectangle_ManipulationStarting;
                rectangle.ManipulationStarted += rectangle_ManipulationStarted;
                rectangle.ManipulationInertiaStarting += rectangle_ManipulationInertiaStarting;
                rectangle.ManipulationCompleted += rectangle_ManipulationCompleted;
                rectangle.ManipulationDelta += rectangle_ManipulationDelta;
            }
    
            void rectangle_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
            {
                _previousTransform.Matrix = _transformGroup.Value;
    
                // 获取操作点相对于此 GeneralTransform 的位置
                Point center = _previousTransform.TransformPoint(new Point(e.Position.X, e.Position.Y));
                _compositeTransform.CenterX = center.X;
                _compositeTransform.CenterY = center.Y;
    
                _compositeTransform.Rotation = e.Delta.Rotation;
                _compositeTransform.ScaleX = e.Delta.Scale;
                _compositeTransform.ScaleY = e.Delta.Scale;
                _compositeTransform.TranslateX = e.Delta.Translation.X;
                _compositeTransform.TranslateY = e.Delta.Translation.Y;
            }
    
            void rectangle_ManipulationStarting(object sender, ManipulationStartingRoutedEventArgs e)
            {
                lblMsg.Text += "ManipulationStarting";
                lblMsg.Text += Environment.NewLine;
            }
    
            void rectangle_ManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
            {
                lblMsg.Text += "ManipulationStarted";
                lblMsg.Text += Environment.NewLine;
            }
    
            void rectangle_ManipulationInertiaStarting(object sender, ManipulationInertiaStartingRoutedEventArgs e)
            {
                lblMsg.Text += "ManipulationInertiaStarting";
                lblMsg.Text += Environment.NewLine;
            }
    
            void rectangle_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
            {
                lblMsg.Text += "ManipulationCompleted";
                lblMsg.Text += Environment.NewLine;
            }
        }
    }


    2、演示路由事件的注册, 路由事件的冒泡, 命中测试的可见性
    Controls/BaseControl/UIElementDemo/EventDemo.xaml

    <Page
        x:Class="Windows10.Controls.BaseControl.UIElementDemo.EventDemo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:Windows10.Controls.BaseControl.UIElementDemo"
        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="10 0 10 10">
    
                <Grid HorizontalAlignment="Left" VerticalAlignment="Top" Margin="5">
                    <!--
                        演示事件冒泡:儿子传递事件给爸爸,爸爸传递事件给爷爷,这就是事件冒泡
                    -->
                    <Border Name="borderRed" Background="Red" Width="300" Height="300">
                        <Border Name="borderGreen" Background="Green" Width="250" Height="250" Tapped="borderGreen_Tapped">
                            <Border Name="borderBlue" Background="Blue" Width="200" Height="200" Tapped="borderBlue_Tapped">
                                <Border Name="borderOrange" Background="Orange" Width="150" Height="150" Tapped="borderOrange_Tapped">
                                    <!--通过 IsHitTestVisible="False" 设置命中测试不可见,也就是说 borderPurple 和 borderYellow 均命中测试不可见-->
                                    <Border Name="borderPurple" Background="Purple" Width="100" Height="100" Tapped="borderPurple_Tapped" IsHitTestVisible="False">
                                        <Border Name="borderYellow" Background="Yellow" Width="50" Height="50" Tapped="borderYellow_Tapped" />
                                    </Border>
                                </Border>
                            </Border>
                        </Border>
                    </Border>
    
                    <!--
                        像这样排列元素,是没有事件冒泡的,而只是前面的元素响应事件,后面的元素不会响应事件,也就是说同辈间没有事件冒泡的概念
                        IsHitTestVisible - 是否对命中测试可见(如果需要后面的元素响应事件,而前面的元素不响应事件,则只需要把前面的元素的命中测试设置为不可见即可)
                        <Rectangle Name="rectangle1" Width="200" Height="200" Fill="Red" />
                        <Rectangle Name="rectangle2" Width="200" Height="200" Fill="Green" />
                        <Rectangle Name="rectangle3" Width="200" Height="200" Fill="Blue" />
                        <Rectangle Name="rectangle4" Width="200" Height="200" Fill="Orange" />
                        <Rectangle Name="rectangle5" Width="200" Height="200" Fill="Purple" />
                    -->
                </Grid>
    
                <TextBlock Name="lblMsg" Margin="5" />
    
            </StackPanel>
        </Grid>
    </Page>

    Controls/BaseControl/UIElementDemo/EventDemo.xaml.cs

    /*
     * UIElement - UIElement(继承自 DependencyObject, 请参见 /Controls/BaseControl/DependencyObjectDemo/)
     *     IsHitTestVisible - 是否对命中测试可见
     *     AddHandler(RoutedEvent routedEvent, object handler, bool handledEventsToo) - 注册一个路由事件,注意最后一个参数:true 代表即使子辈 TappedRoutedEventArgs.Handled = true 也不会影响此元素事件的触发
     *     RemoveHandler(RoutedEvent routedEvent, object handler) - 移除指定的路由事件
     *     
     *     
     * RoutedEventArgs - 路由事件参数(有 n 多的派生类)
     *     OriginalSource - 引发此路由事件的对象
     * 
     * TappedRoutedEventArgs - Tapped 事件参数(继承自 RoutedEventArgs,详细说明请参见 /Controls/BaseControl/DependencyObjectDemo/TapDemo.xaml)
     *     Handled - 是否将路由事件标记为已处理
     *         true - 不再冒泡
     *         false - 继续冒泡
     *         
     *         
     * 本例用于演示 UIElement 的路由事件的注册,路由事件的冒泡,命中测试的可见性   
     */
    
    using System;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Input;
    
    
    namespace Windows10.Controls.BaseControl.UIElementDemo
    {
        public sealed partial class EventDemo : Page
        {
            public EventDemo()
            {
                this.InitializeComponent();
    
                // 为 borderRed 注册一个 TappedEventHandler 路由事件(注意最后一个参数:true 代表即使子辈 TappedRoutedEventArgs.Handled = true 也不会影响此元素事件的触发)
                borderRed.AddHandler(UIElement.TappedEvent, new TappedEventHandler(borderRed_Tapped), true);
            }
    
            private void borderRed_Tapped(object sender, TappedRoutedEventArgs e)
            {
                lblMsg.Text += "borderRed tapped, originalSource: " + (e.OriginalSource as FrameworkElement).Name;
                lblMsg.Text += Environment.NewLine;
            }
    
            private void borderGreen_Tapped(object sender, TappedRoutedEventArgs e)
            {
                lblMsg.Text += "borderGreen tapped, originalSource: " + (e.OriginalSource as FrameworkElement).Name;
                lblMsg.Text += Environment.NewLine;
            }
    
            private void borderBlue_Tapped(object sender, TappedRoutedEventArgs e)
            {
                lblMsg.Text += "borderBlue tapped, originalSource: " + (e.OriginalSource as FrameworkElement).Name;
                lblMsg.Text += Environment.NewLine;
    
                // 不会再冒泡,也就是说 borderGreen 无法响应 Tapped 事件,但是 borderRed 注册 Tapped 事件时 handledEventsToo = true,所以 borderRed 会响应 Tapped 事件
                e.Handled = true;
            }
    
            private void borderOrange_Tapped(object sender, TappedRoutedEventArgs e)
            {
                lblMsg.Text += "borderOrange tapped, originalSource: " + (e.OriginalSource as FrameworkElement).Name;
                lblMsg.Text += Environment.NewLine;
            }
    
            private void borderPurple_Tapped(object sender, TappedRoutedEventArgs e)
            {
                // 不会响应此事件,因为 borderPurple 的 IsHitTestVisible = false
                lblMsg.Text += "borderPurple tapped, originalSource: " + (e.OriginalSource as FrameworkElement).Name;
                lblMsg.Text += Environment.NewLine;
            }
    
            private void borderYellow_Tapped(object sender, TappedRoutedEventArgs e)
            {
                // 不会响应此事件,因为 borderYellow 的爸爸 borderPurple 的 IsHitTestVisible = false
                lblMsg.Text += "borderYellow tapped, originalSource: " + (e.OriginalSource as FrameworkElement).Name;
                lblMsg.Text += Environment.NewLine;
            }
        }
    }



    OK
    [源码下载]

  • 相关阅读:
    MySQL存储树形数据优化技笔记
    收集18个高大上的浏览器小技巧
    收集18个高大上的浏览器小技巧
    盘点15个不起眼但非常强大的 Vim 命令
    盘点15个不起眼但非常强大的 Vim 命令
    为什么开发者应该摒弃敏捷?(转)
    为什么开发者应该摒弃敏捷?(转)
    MySQL 中事务、事务隔离级别详解
    pandas数据对齐
    Bokeh绘图
  • 原文地址:https://www.cnblogs.com/webabcd/p/7675556.html
Copyright © 2011-2022 走看看