将一些方法从代码隐藏中移动

本文关键字:隐藏 移动 代码 方法 | 更新日期: 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,但我不知道如何将ManipulationDeltaRoutedEventArgsXaml.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的解决方案而不是这个。