WPF UserControl 中的缩放/捏合检测 [英] Zoom/Pinch detection in a WPF UserControl
本文介绍了WPF UserControl 中的缩放/捏合检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想知道如何检测 UserControl 上的缩放/捏合手势?以下是我的 XAML 代码.我如何在Grid_OnManipulationDelta"或Grid_OnManipulationCompleted"方法中检测到这一点?提前感谢您的帮助.
I want to know how can I detect a Zoom/pinch gesture made on UserControl? Following is my XAML code. How can i detect this in "Grid_OnManipulationDelta" or "Grid_OnManipulationCompleted" methods? Thanx for the help in advance.
<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>
推荐答案
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
}
}
}
这篇关于WPF UserControl 中的缩放/捏合检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文