【问题标题】:Zoom/Pinch detection in a WPF UserControlWPF 用户控件中的缩放/捏合检测
【发布时间】:2014-11-09 19:03:12
【问题描述】:

我想知道如何检测 UserControl 上的缩放/捏合手势? 以下是我的 XAML 代码。如何在“Grid_OnManipulationDelta”或“Grid_OnManipulationCompleted”方法中检测到这一点? 提前感谢您的帮助。

<UserControl x:Class="HCMainWPF.Views.MainView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:views="clr-namespace:HCMainWPF.Views" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" Name="ZMainView">
    <Canvas x:Name="grid">
        <Canvas.RenderTransform>
            <ScaleTransform x:Name="zoom" ScaleX="1" ScaleY="1" />
        </Canvas.RenderTransform>
        <Canvas.Triggers>
            <EventTrigger RoutedEvent="Grid.ManipulationCompleted">
                <EventTrigger.Actions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Duration="00:00:02" From="320" Storyboard.TargetName="ZMainView"
                        Storyboard.TargetProperty="Height"  To="960"/>
                            <DoubleAnimation Duration="00:00:02" From="270" Storyboard.TargetName="ZMainView"
                        Storyboard.TargetProperty="Width" To="810"/>
                            <DoubleAnimation Duration="00:00:02" From="1" Storyboard.TargetName="zoom"
                        Storyboard.TargetProperty="ScaleX" To="3"/>
                            <DoubleAnimation Duration="00:00:02" From="1" Storyboard.TargetName="zoom"
                        Storyboard.TargetProperty="ScaleY" To="3"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger.Actions>
            </EventTrigger>
        </Canvas.Triggers>
        <Grid Height="280" Width="280" IsManipulationEnabled="True"
            ManipulationStarting="Grid_OnManipulationStarting"
            ManipulationDelta="Grid_OnManipulationDelta" 
            ManipulationCompleted="Grid_OnManipulationCompleted">
            <Grid.RowDefinitions>
                <RowDefinition Height="1.66*"/>
                <RowDefinition Height="1.66*"/>
                <RowDefinition Height="1.66*"/>
                <RowDefinition Height="1.66*"/>
                <RowDefinition Height="1.66*"/>
                <RowDefinition Height="1.66*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="3.33*"/>
                <ColumnDefinition Width="3.33*"/>
                <ColumnDefinition Width="3.33*"/>
            </Grid.ColumnDefinitions>
        </Grid>
    </Canvas>
</UserControl>

【问题讨论】:

  • 嗨,你能找到任何解决方案吗?如何检测捏合/捏合事件?

标签: wpf touch zooming pinchzoom


【解决方案1】:

简而言之,是的。使用捏合/缩放手势启动和运行的最快方法是将“TranslateZoomRotateBehavior”附加到您要控制的用户控件或元素。这将允许您使用单点触控和多点触控事件来控制元素的平移、缩放和旋转。

如果您想手动执行此操作,那么我建议您查看此行为的自定义版本I've posted on Codeplex

特别是ManipulationDeltaHandler in this class

【讨论】:

    【解决方案2】:
     public class GestureDetector
    {
        private readonly uint _pixelPerCm = 38;
        private bool _isGestureDetected = false;
    
        public bool IsPanningAllowed { get; private set; }
        public bool IsScalingAllowed { get; private set; }
        public bool IsRotatingAllowed { get; private set; }
    
        public GestureDetector(FrameworkElement uiElement)
        {
            IsPanningAllowed = false;
            IsScalingAllowed = false;
            IsRotatingAllowed = false;
    
            uiElement.ManipulationStarted += (sender, args) =>
            {
                IsPanningAllowed = true;
            };
    
            double scale = 0.0d;
            double rot = 0.0d;
    
            uiElement.ManipulationDelta += (sender, args) =>
            {
                const double MIN_SCALE_TRIGGER = 0.05;
                const int MIN_ROTATIONANGLE_TRIGGER_DEGREE = 10;
                const int MIN_FINGER_DISTANCE_FOR_ROTATION_CM = 2;
    
                var manipulatorBounds = Rect.Empty;
                foreach (var manipulator in args.Manipulators)
                {
                    manipulatorBounds.Union(manipulator.GetPosition(sender as IInputElement));
                }
    
                var distance = (manipulatorBounds.TopLeft - manipulatorBounds.BottomRight).Length;
                var distanceInCm = distance /_pixelPerCm;
    
                scale += 1-(args.DeltaManipulation.Scale.Length / Math.Sqrt(2));
    
                rot += args.DeltaManipulation.Rotation;
    
                if (Math.Abs(scale) > MIN_SCALE_TRIGGER && Math.Abs(rot) < MIN_ROTATIONANGLE_TRIGGER_DEGREE)
                {
                    ApplyScaleMode();
                }
    
                if (Math.Abs(rot) >= MIN_ROTATIONANGLE_TRIGGER_DEGREE && distanceInCm > MIN_FINGER_DISTANCE_FOR_ROTATION_CM)
                {
                    ApplyRotationMode();
                }
            };
    
            uiElement.ManipulationCompleted += (sender, args) =>
            {
                scale = 0.0d;
                rot = 0.0d;
                IsPanningAllowed = false;
                IsScalingAllowed = false;
                IsRotatingAllowed = false;
                _isGestureDetected = false;
            };
        }
    
        private void ApplyScaleMode()
        {
            if (!_isGestureDetected)
            {
                _isGestureDetected = true;
                IsPanningAllowed = true;
                IsScalingAllowed = true;
                IsRotatingAllowed = false;
            }
        }
    
        private void ApplyRotationMode()
        {
            if (!_isGestureDetected)
            {
                _isGestureDetected = true;
                IsPanningAllowed = true;
                IsScalingAllowed = true;
                IsRotatingAllowed = true;
            }
        }
    }
    

    用法:

     private void uielement_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
        {
            {
                if (_gestureDetector.IsPanningAllowed)
                {
                   // Translate
                }
            }
    
            {
                if (_gestureDetector.IsScalingAllowed)
                {
                   // Scale
                }
            }
    
            {
                if (_gestureDetector.IsRotatingAllowed)
                {
                    // Rotate
                }
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2017-10-28
      • 1970-01-01
      • 2011-06-16
      • 2012-01-29
      • 1970-01-01
      • 2011-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多