我的View
上有6张图片,如Xaml.Image
。我需要移动,旋转和缩放它。这是我的xaml
代码,例如1张图片。
<Image Width="525"
Height="331"
Canvas.Top="-199"
Canvas.Left="-733"
x:Name="CollageImg1"
ManipulationMode="All"
Source="{Binding CollageImg1}"
ManipulationDelta="CollageImgage1_Manipulation">
<Image.RenderTransform>
<CompositeTransform/>
</Image.RenderTransform>
</Image>
对于我的所有操作,我对代码隐藏中的每个图像都有方法collageImgage1_Manipulation
。
private void CollageImgage1_Manipulation(object sender, ManipulationDeltaRoutedEventArgs e)
{
ImageManipulator.Manipulation(e, CollageImg1);
}
所有图像的一般方法
public static void Manipulation(ManipulationDeltaRoutedEventArgs e, Image xamlimage)
{
CompositeTransform ct = (CompositeTransform)xamlimage.RenderTransform;
ct.ScaleX *= e.Delta.Scale;
ct.ScaleY *= e.Delta.Scale;
ct.TranslateX += e.Delta.Translation.X;
ct.TranslateY += e.Delta.Translation.Y;
ct.Rotation += Math.PI * e.Delta.Rotation;
}
我尝试制作Command
,但我不知道如何将ManipulationDeltaRoutedEventArgs
和Xaml.Image
转移到其他课程中的方法
答案 0 :(得分:0)
更新:旧代码在UWP / WP8.1中不起作用,但仅在WPF中有效!
相反,我创建了一个派生自ContentControl
的类,它支持在ManipulationDelta
事件被引发时触发命令。虽然可能有更精确的名称描述了课程的动作,但我称之为ManipulationContentControl
。
using System;
using System.Windows.Input;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
public class ManipulationContentControl
: ContentControl
{
public static readonly DependencyProperty ManipulationCommandProperty =
DependencyProperty.Register(
nameof(ManipulationCommand),
typeof(ICommand),
typeof(ManipulationContentControl),
new PropertyMetadata(default(ICommand)));
public ICommand ManipulationCommand
{
get { return (ICommand)this.GetValue(ManipulationCommandProperty); }
set { this.SetValue(ManipulationCommandProperty, value); }
}
}
然后我为传递给命令的参数创建了一个类。
public class ManipulationCommandArgs
{
public ManipulationCommandArgs(
CompositeTransform target,
ManipulationDeltaRoutedEventArgs eventArgs)
{
if (object.ReferenceEquals(target, null))
{
throw new ArgumentNullException(nameof(target));
}
if (object.ReferenceEquals(eventArgs, null))
{
throw new ArgumentNullException(nameof(eventArgs));
}
this.Target = target;
this.EventArgs = eventArgs;
}
public CompositeTransform Target { get; private set; }
public ManipulationDeltaRoutedEventArgs EventArgs { get; private set; }
}
之后我需要为我的ManipulationContentControl
类实现事件处理程序。
public ManipulationContentControl()
{
this.ManipulationDelta += this.ManipulationImage_ManipulationDelta;
}
private void ManipulationImage_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
var transform = this.RenderTransform as CompositeTransform;
if (object.ReferenceEquals(e, null) ||
object.ReferenceEquals(transform, null))
{
return;
}
var args = new ManipulationCommandArgs(transform, e);
if (this.ManipulationCommand?.CanExecute(args) == true)
{
this.ManipulationCommand.Execute(args);
}
}
最后,您可以在XAML中使用ManipulationContentControl
类,并在其中嵌入Image
。 与操作相关的所有属性都应该应用于ManipulationContentControl
而不是Image
!
此示例假定ManipulationContentControl
类与XAML代码位于同一名称空间中。
<local:ManipulationContentControl ManipulationCommand="{Binding YourCommand}" ManipulationMode="All">
<local:ManipulationContentControl.RenderTransform>
<CompositeTransform />
</local:ManipulationContentControl.RenderTransform>
<Image ... />
</local:ManipulationContentControl>
对于{Binding YourCommand}
,您应该实施RelayCommand
class。本教程中的RelayCommand
类也适用于UWP和WP8 / 8.1。
然后创建一个包含操作代码的方法的RelayCommand
类的实例。
public RelayCommand YourCommand { get; } = new RelayCommand(
arg =>
{
var param = arg as ManipulationCommandArgs;
if (object.ReferenceEquals(arg, null))
{
throw new ArgumentException(); // or return
}
// below you can insert your manipulation code as in your event handler,
// but use 'param.Target' instead of 'ct' and 'param.EventArgs.Delta' instead of 'e.Delta'
});
我希望这些代码段对您有用!
编辑:我的解决方案适用于UWP,因为没有集成的Behavior<T>
支持,但在WPF中,您应该更喜欢UI操作的行为,如MichaelThePotato所述。
本文可能会对您有所帮助:https://blogs.windows.com/buildingapps/2015/11/30/xaml-behaviors-open-source-and-on-uwp/。它通过微软发布的NuGet软件包宣布了UWP应用程序的行为可用性。如果这个包正常,你应该更喜欢MichaelThePotato的解决方案。
答案 1 :(得分:0)
执行此操作的简单方法可能是通过行为。 如果您正在使用WPF -
internal class ManipulationDeltaCommandBehavior : Behavior<UIElement>
{
public ICommand ManipulationDeltaCommand { get; set; }
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.ManipulationDelta += OnManipulationDelta;
}
private void OnManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
ManipulationDeltaCommand.Execute(e);
}
}
这样您就可以将事件及其参数传递给VM。 或者更好的是,通过行为在UI中完成所有UI工作!我认为那要好得多。
internal class ManipulationDeltaCommandBehavior : Behavior<UIElement>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.ManipulationDelta += OnManipulationDelta;
}
private void OnManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
// Do the work here! AssociatedObject is the Image
}
}