在MVVM Light中传递MouseEvent Args

时间:2017-12-05 08:32:56

标签: c# wpf xaml mvvm mvvm-light

我正在编写一个应用程序,我可以通过鼠标裁剪和调整图像大小。因为我在确定如何在MVVM中传递Event Args时遇到了问题,所以我决定尝试使用MVVM Light。现在,每当我的鼠标在图像上时,我都会收到错误:

  

未处理的类型' System.InvalidCastException'发生在GalaSoft.MvvmLight.Platform.dll

     

其他信息: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类型工作。 我怎样才能解决这个问题?或者我的方法是错的?非常感谢任何帮助或建议。

1 个答案:

答案 0 :(得分:0)

您正在将MouseButtonEventArgs转换为MouseButtonEventArgsToPointConverter中的一个点,但命令期望MouseButtonEventArgs参数 - 因此是强制转换异常。您将其转换为Point,然后将Point传递给RelayCommand<MouseButtonEventArgs>,然后尝试将Point投射到MouseButtonEventArgs,这显然不能做。你想通过Point或事件args吗?如果是,则将命令更改为RelayCommand<Point>,如果是事件参数,则删除转换器的使用

或者:

 <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
    {
        ...
    }
}