2017-12-05 58 views
0

마우스로 이미지를 자르고 크기를 조정할 수있는 응용 프로그램을 프로그래밍하고 있습니다. MVVM에서 Event Args를 전달하는 방법에 문제가 있었기 때문에 MVVM Light를 시험해보기로 결정했습니다. 난 정말 내 RelayCommands 잘못 구현한다고 가정하더라도이 문제를 해결하는 방법을 모르는MVVM 라이트에서 MouseEvent 인수 전달

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 :

<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

MouseButtonEventArgsMouseButtonEventArgsToPointConverter의 포인트로 변환하지만 명령에 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

포인트 업데이트 된 답변을 받으려면 MouseDown 함수를 업데이트해야합니다. –