在 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
{
...
}
}
我正在编写一个应用程序,我可以在其中通过鼠标裁剪和调整图像大小。因为我无法弄清楚如何在 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
{
...
}
}