将一些方法从代码隐藏中移动
本文关键字:隐藏 移动 代码 方法 | 更新日期: 2023-09-27 17:58:30
我的View
上有6张像Xaml.Image
一样的图片。我需要移动、旋转和缩放它。这是我的1个图像的xaml
代码,例如
<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>
对于我所有的操作,我在codeehind中为每个图像都有方法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
转移到其他类中的方法
一个简单的方法可能是通过Behavior。如果你正在进行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
}
}
UPDATE:旧代码在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
类。本教程中的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的解决方案而不是这个。