Передача MouseEvent Args в MVVM Light

90
8

Я программирую приложение, где я могу обрезать и изменять размер изображения с помощью мыши. Поскольку у меня были проблемы с выяснением того, как я могу передать Event Args в MVVM, я решил попробовать MVVM Light. Теперь каждый раз, когда моя мышь находится над изображением, я получаю сообщение об ошибке:

Необработанное исключение типа "System.InvalidCastException" произошло в GalaSoft.MvvmLight.Platform.dll

Дополнительная информация: Das Objekt des Typs "System.Windows.Point" kann nicht в 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;
}
}

Я также придерживался этого совета по аналогичному вопросу, если не тот же вопрос, но RelayCommand не будет работать как точка типа. Как я могу это исправить? Или мой подход неправильный? Очень благодарен за любую помощь или предложения.

спросил(а) 2017-12-05T11:32:00+03:00 2 года, 10 месяцев назад
1
Решение
81

Вы конвертируете MouseButtonEventArgs в точку в MouseButtonEventArgsToPointConverter но команды ожидают параметр MouseButtonEventArgs - следовательно, исключение cast. Вы конвертируете его в Point а затем Point передается в RelayCommand<MouseButtonEventArgs>, затем делается попытка бросить Point на MouseButtonEventArgs чего, очевидно, не может сделать. Вы хотите передать Point или события args? Если точка затем изменит команду на RelayCommand<Point>, если события args затем удаляют использование преобразователя

Или:

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

ответил(а) 2017-12-05T11:42:00+03:00 2 года, 10 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема