在我看来,我有:
<UserControl x:Class ... MouseDown="UserControl_MouseDown">
<Viewport3D Name="Viewport" Grid.Column="0">
...
</Viewport3D >
</UserControl>
在我的代码隐藏中,我有:
private void UserControl_MouseDown(object sender, MouseButtonEventArgs e)
{
((MapPanelViewModel)DataContext).OnMouseDown(e, Viewport);
}
在我的视图模型中,我有:
public void OnMouseDown(MouseEventArgs e, Viewport3D viewport)
{
var range = new LineRange();
var isValid = ViewportInfo.Point2DtoPoint3D(viewport, e.GetPosition(viewport), out range);
if (!isValid)
MouseCoordinates = "(no data)";
else
{
var point3D = range.PointFromZ(0);
var point = ViewportInfo.Point3DtoPoint2D(viewport, point3D);
MouseCoordinates = e.GetPosition(viewport).ToString() + "\n" + point3D + "\n" + point;
}
}
我真的不太了解如何使用MVVM处理鼠标事件。我总是将它们放在代码隐藏中并将DataContext
转换为SomeViewModel
,然后将MouseEventArgs
传递给我的视图模型中的处理程序。这已经够糟糕了,但在这种情况下,我实际上是在传递一个控件(Viewport3D
),这对于在2D和3D之间转换坐标是必要的。
有关如何使其与MVVM更加协调的任何建议吗?
答案 0 :(得分:2)
我认为这是将MVVM推得太远的一个案例。当然,MVVM并没有精确定义,但我想到的是尝试将我的应用程序高级机制和行为与使用特定UI技术实现这些机制和行为的细节分开(现在只是WPF)当然,但我觉得假装可能还有别的东西很有用。
在不知道您的应用程序应如何对鼠标事件作出反应的情况下,很难给出具体的建议或意见。基于我做看到的内容,我认为坐标转换最好保留在UI层中,然后翻译的坐标将通过方法调用传递给ViewModel。
答案 1 :(得分:1)
如果您担心通过将View对象传递给ViewModel来破坏可测试性,请创建一个用于在3D和2D点之间进行转换的接口,并将其传递给它。在您的代码中,然后将Viewport3D
对象传递给实现该接口的包装器。
除此之外我不会担心代码背后的事件处理程序。对所有容易使用的绑定使用绑定,使用背后的代码来处理非常棘手的部分。
答案 2 :(得分:0)
我最终使用了MVVM Messenger。因此,鼠标事件在后面的代码中处理,然后它发送事件发生的消息。然后,我的ViewModel可以订阅此消息并接收通知。像魅力一样工作,让一切都解耦。