6

我有一个我认为简单的情况,但似乎无法弄清楚如何完成它。我对 WPF 和 Caliburn Micro 框架非常陌生。在我看来,我有一个画布,在这个画布上我有一个图像。我想编写一些鼠标事件处理程序(MouseLeftButtonDown、MouseLeftButtonUp 和 MouseMove),当光标在图像内时调用它们。我已经成功地能够在 ViewModel 中创建事件处理程序,但我似乎无法弄清楚如何在处理程序中获取当前光标位置。MouseEventArgs.GetPosition 需要一个 IInputElement 作为参数......不知道如何得到它。

这是我的 XAML(视图):

<Canvas x:Name="ImageCanvas" >    
    <Image Source="{Binding DataImage}" 
           x:Name="ContainerImage"
              cal:Message.Attach=
              "[Event MouseLeftButtonDown] = [Action MouseDown_Image($source, $eventArgs)];
               [Event MouseLeftButtonUp] = [Action MouseUp_Image($source, $eventArgs)];
               [Event MouseMove] = [Action MouseMove_Image($source, $eventArgs)]">
    </Image>
</Canvas>

这是我的 C# (viewmodel)

public void MouseDown_Image(object sender, MouseEventArgs e)
    {
      // How do I get cursor position here??

      // convert to Image coordinates??
    }

public void MouseUp_Image(object sender, MouseEventArgs e)
    {
      // How do I get cursor position here??

      // convert to Image coordinates??
    }

public void MouseMove_Image(object sender, MouseEventArgs e)
    {
      // How do I get cursor position here??

      // convert to Image coordinates??
    }

完成此操作后,我需要将鼠标坐标转换为图像上的坐标……但首先要做的是。

谢谢!!

4

2 回答 2

6

SpecialValues制作字典条目以处理图像的坐标可能很有用- 这样您就可以在中心位置添加功能,甚至只取图像中的 X/Y 位置或另一个缩放输入控件:

例如在您的 CM Bootstrapper 配置中:

            MessageBinder.SpecialValues.Add("$scaledmousex", (ctx) =>
            {
                var img = ctx.Source as Image;
                var input = ctx.Source as IInputElement;
                var e = ctx.EventArgs as MouseEventArgs;

                // If there is an image control, get the scaled position
                if (img != null && e != null)
                {
                    Point position = e.GetPosition(img);
                    return (int)(img.Source.Width * (position.X / img.ActualWidth));
                }

                // If there is another type of of IInputControl get the non-scaled position - or do some processing to get a scaled position, whatever needs to happen
                if (e != null && input != null)
                    return e.GetPosition(input).X;

                // Return 0 if no processing could be done
                return 0;
            });

该字典用于解析您的操作消息绑定中的输入参数,并将运行上述匿名委托,返回您指定的值(您还需要添加$scaledmousey

然后在绑定中使用这个值:

cal:Message.Attach="[Event MouseMove] = [Action MouseMove_Image($scaledmousex, $scaledmousey)]"

这样,如果您决定要更改源类型,您仍然可以在没有太多/任何重构的情况下获得该位置,并且您的代码会通过中央处理路径

这也确保了视图/视图模型是解耦的 - MVVM 模式的目标的一部分

于 2013-07-02T10:54:38.637 回答
0

我相信我已经解决了!

在我的 XAML 中,我将事件处理程序附加到 Image 对象上的事件。因此,我的事件处理程序中的发件人可以转换为 Image 类型。然后,您可以将发件人作为参数传递给 GetPosition。

此外,我能够将发送的坐标转换为实际图像坐标。知道原始图像的像素大小,这只是一些简单的缩放数学。

这是我的鼠标处理程序之一的代码:

public void MouseDown_Image(object sender, MouseEventArgs e)
   {

      // Get the x and y coordinates of the mouse pointer.
       System.Windows.Point position = e.GetPosition((Image)sender);
       int pX = (int)position.X;
       int pY = (int)position.Y;

     // DataImage is the actual Image object that is being shown in the view
       int X_ImageCoordinates = (int)(DataImage.PixelWidth * (position.X/img.ActualWidth));
       int Y_ImageCoordinates = (int)(DataImage.PixelHeight * (position.Y / img.ActualHeight));                
    }

结果很简单!应该如此。

如果有更好的解决方案,或者由于某种原因我犯了错误,请告诉我。

谢谢!!

于 2013-07-01T23:29:16.683 回答