从代码隐藏中移出一些方法

时间:2016-07-23 07:38:28

标签: c# wpf xaml mvvm uwp

我的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,但我不知道如何将ManipulationDeltaRoutedEventArgsXaml.Image转移到其他课程中的方法

2 个答案:

答案 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
    }
}