我正在编写一个应用程序,我可以通过鼠标裁剪和调整图像大小。因为我在确定如何在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类型工作。 我怎样才能解决这个问题?或者我的方法是错的?非常感谢任何帮助或建议。
答案 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
{
...
}
}