在 MVVM Light 中传递 MouseEvent 参数

Passing MouseEvent Args in MVVM Light

我正在编写一个应用程序,我可以在其中通过鼠标裁剪和调整图像大小。因为我无法弄清楚如何在 MVVM 中传递事件参数,所以我决定尝试一下 MVVM Light。现在,每次我的鼠标悬停在图像上时,我都会收到错误消息:

An unhandled exception of type 'System.InvalidCastException' occurred in GalaSoft.MvvmLight.Platform.dll

Additional information: Das Objekt des Typs "System.Windows.Point" kann nicht in Typ "System.Windows.Input.MouseEventArgs" umgewandelt werden.

虽然我认为我的 RelayCommands 实施错误,但我真的不知道如何解决这个问题。

我在 XAML 中做了如下绑定:

 <Image x:Name="_image" Margin="10" Source="{Binding CurrentImage.ImagePath, UpdateSourceTrigger=PropertyChanged}"
               HorizontalAlignment="Left" VerticalAlignment="Top" Stretch="Fill" MaxHeight="300">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseDown">
                    <cmd:EventToCommand Command="{Binding Mode=OneWay, Path=MouseDownCommand}"
                                        EventArgsConverter="{StaticResource MouseButtonEventArgsToPointConverter}"
                                        EventArgsConverterParameter="{Binding ElementName=_image}"
                                        PassEventArgsToCommand="True" />
                </i:EventTrigger>
                <i:EventTrigger EventName="MouseMove">
                    <cmd:EventToCommand Command="{Binding Mode=OneWay, Path=MouseMoveCommand}"
                                        EventArgsConverter="{StaticResource MouseEventArgsToPointConverter}"
                                        EventArgsConverterParameter="{Binding ElementName=_image}"
                                        PassEventArgsToCommand="True" />
                </i:EventTrigger>
                <i:EventTrigger EventName="MouseUp">
                    <cmd:EventToCommand Command="{Binding Mode=OneWay, Path=MouseUpCommand}"
                                        EventArgsConverter="{StaticResource MouseButtonEventArgsToPointConverter}"
                                        EventArgsConverterParameter="{Binding ElementName=_image}"
                                        PassEventArgsToCommand="True" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Image>

我的 ViewModel 如下所示:

RelayCommand<MouseButtonEventArgs> mouseDownCommand;
    public RelayCommand<MouseButtonEventArgs> MouseDownCommand
    {
        get
        {
            if (mouseDownCommand == null)
            {
                mouseDownCommand = new RelayCommand<MouseButtonEventArgs>(MouseDown);
            }
            return mouseDownCommand;
        }
    }

    public void MouseDown(MouseButtonEventArgs e)
    {
        this.currentImage.StartPoint = e.GetPosition(this.currentImage.CnvImage);
    }

    RelayCommand<System.Windows.Input.MouseEventArgs> mouseMoveCommand;
    public RelayCommand<System.Windows.Input.MouseEventArgs> MouseMoveCommand
    {
      get
        {
            if (mouseMoveCommand == null)
            {
                mouseMoveCommand = new RelayCommand<System.Windows.Input.MouseEventArgs>(MouseMove);
            }
            return mouseMoveCommand;
        }
    }

    public void MouseMove(System.Windows.Input.MouseEventArgs e)
    {
        if (e.LeftButton == MouseButtonState.Pressed)
        {
            var pos = e.GetPosition(this.currentImage.CnvImage);

            var x = Math.Min(pos.X, this.currentImage.StartPoint.X);
            var y = Math.Min(pos.Y, this.currentImage.StartPoint.Y);

            var w = Math.Max(pos.X, this.currentImage.StartPoint.X) - x;
            var h = Math.Max(pos.Y, this.currentImage.StartPoint.Y) - y;

            var rect = new System.Windows.Shapes.Rectangle
            {
                Stroke = System.Windows.Media.Brushes.LightBlue,
                StrokeThickness = 2
            };

            this.currentImage.RectSelectArea = rect;

            this.currentImage.RectSelectArea.Width = w;
            this.currentImage.RectSelectArea.Height = h;

            Canvas.SetLeft(this.currentImage.RectSelectArea, x);
            Canvas.SetTop(this.currentImage.RectSelectArea, y);
        }
    }

    RelayCommand<MouseButtonEventArgs> mouseUpCommand;
    public RelayCommand<MouseButtonEventArgs> MouseUpCommand
    {
       get
        {
            if (mouseUpCommand == null)
            {
                mouseUpCommand = new RelayCommand<MouseButtonEventArgs>(MouseUp);
            }
            return mouseUpCommand;
        }
    }

    public void MouseUp(MouseButtonEventArgs e)
    {
        System.Windows.Controls.Image croppedImage = new System.Windows.Controls.Image();
        croppedImage.Width = 100;
        croppedImage.Margin = new Thickness(5);

        this.currentImage.CropXPosition = (int)this.currentImage.StartPoint.X;
        this.currentImage.CropYPosition = (int)this.currentImage.StartPoint.Y;
        this.currentImage.CropWidth = (int)this.currentImage.RectSelectArea.Width;
        this.currentImage.CropHeight = (int)this.currentImage.RectSelectArea.Height;
        CroppedBitmap cb = new CroppedBitmap(
            (BitmapSource)this.currentImage.ImagePath, new Int32Rect(
                this.currentImage.CropXPosition, this.currentImage.CropYPosition, this.currentImage.CropWidth, this.currentImage.CropHeight));
        croppedImage.Source = cb;
    }

MouseButtonEventToArgsToPointConverter:

  class MouseButtonEventArgsToPointConverter : IEventArgsConverter
{
    public object Convert(object value, object parameter)
    {
        var args = (MouseButtonEventArgs)value;
        var element = (FrameworkElement)parameter;

        var point = args.GetPosition(element);
        return point;
    }
}

我也遵循了来自类似问题的 this 建议,如果不是同一个问题,但 RelayCommand 不能作为 Point 类型工作。 我怎样才能解决这个问题?还是我的方法不对?非常感谢任何形式的帮助或建议。

您正在将 MouseButtonEventArgs 转换为 MouseButtonEventArgsToPointConverter 中的一个点,但这些命令需要一个 MouseButtonEventArgs 参数 - 因此出现强制转换异常。您将其转换为 Point,然后将 Point 传递给 RelayCommand<MouseButtonEventArgs>,然后尝试将 Point 转换为 MouseButtonEventArgs,这显然不能做。你想传递点或事件参数吗? If point then change the command to RelayCommand<Point>, if event args then remove the use of the converter

事件参数

或者:

 <cmd:EventToCommand Command="{Binding Mode=OneWay, 
    Path=MouseDownCommand}"                                        
    EventArgsConverter="{StaticResource MouseButtonEventArgsToPointConverter}"                                         
    EventArgsConverterParameter="{Binding ElementName=_image}"
    PassEventArgsToCommand="True" />

public RelayCommand<Point> MouseDownCommand
{
    get
    {
       ...
    }
}

同样在这种情况下,您需要将 MouseDown 更改为:

public void MouseDown(Point p)

或者:

<cmd:EventToCommand Command="{Binding Mode=OneWay, 
    Path=MouseDownCommand}"  PassEventArgsToCommand="True" />

public RelayCommand<MouseButtonEventArgs> MouseDownCommand
{
    get
    {
        ...
    }
}