2017-12-05 29 views
0

マウスで画像をトリミングしてサイズ変更できるアプリケーションをプログラミングしています。 MVVMでEvent Argsをどのように渡すことができたのか、問題があったので、MVVM Lightを試してみることにしました。私は本当に私は私のRelayCommandsが間違って実装されていることを前提としていたが、この問題を解決する方法がわからないMVVMライトでMouseEvent Argingを渡す

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.

:今毎回私のマウスを画像の上で、私はエラーを受け取ります。

私は次のようにXAMLでバインディングをした:

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::私のViewModelには、このようになります

<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> 

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 wタイプポイントとして動作しません。 これを修正するにはどうすればよいですか?または私のアプローチは間違っていますか?どんな種類の助けや提案にも本当に感謝しています。

+0

MouseButtonEventArgsToPointConverter - このコードを投稿できますか? –

+0

@TimRutter編集された投稿のコードを参照してください –

+0

あなたはUIロジックをビューモデルに詰め込んでいます。 MVVM!=コードビハインドなし。 MVVMはビジネスロジックとUIロジックを分離します。あなたのUIロジックはビューのコードビハインドに属します。あなたがやっていることは、このダンスであなた自身のことをもっと難しくすることです。 – Will

答えて

0

MouseButtonEventArgsToPointConverterの点にMouseButtonEventArgsを変換していますが、コマンドにはMouseButtonEventArgsパラメータが必要です。したがって、キャストの例外です。それをPointに変換してPointRelayCommand<MouseButtonEventArgs>に渡すと、PointMouseButtonEventArgsにキャストしようとしますが、これは明らかにできません。 Pointまたはイベント引数を渡しますか?

public void MouseDown(Point p) 

:あなたはこれにMouseDownイベントを変更する必要があり、この場合にも

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

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

:イベント引数は、その後、コンバータの

のいずれかを使用を削除する場合のポイントはその後、RelayCommand<Point>にコマンドを変更した場合または:

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

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

ああ、本当ですが、画像が切り取れるようにポイントの位置を取得する必要があると思いました。 [ここ](http://blog.galasoft.ch/posts/2014/01/using-the-eventargsconverter-in-mvvm-light-and-why-is-there-no-eventtocommand-in-the-windows)を参照してください。 -8-1-version /) –

+0

上記の最初の例を使用してください。あなたのリンクの例を見ると、ShowPositionCommandはRelayCommandです RelayCommand

+0

また、Point-updatedの回答を得るためにMouseDown関数を更新する必要があります。 –

関連する問題