我认为这是一个简单的情况,但似乎无法弄清楚如何完成它。我是WPF和Caliburn Micro框架的新手。在我的视图中,我有一个画布,在这个画布上我有一个图像。我想编写一些鼠标事件处理程序(MouseLeftButtonDown,MouseLeftButtonUp和MouseMove),当光标在Image中时调用它们。我已经成功地在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??
}
一旦我这样做,我需要将鼠标坐标转换为图像上的坐标......但首先要做的事情。
谢谢!
答案 0 :(得分:6)
创建SpecialValues
字典条目以处理图像的坐标可能很有用 - 这样您就可以在中心位置添加功能,或者甚至只在图像中的X / Y位置或另一个缩放输入控件:
e.g。在你的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)]"
这样,如果您决定要更改源类型,您仍然可以在没有太多/任何重构的情况下获得该位置,并且您的代码将通过中央处理路径
这也确保了view / viewmodel被解耦 - MVVM模式的一部分目标
答案 1 :(得分: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));
}
原来很简单!应该如此。
如果有更好的解决方案,或者由于某种原因我犯了错误,请告诉我。
谢谢!