如何在我的WPF 3D应用程序中使用MVVM设置此鼠标下载代码?

如何在我的WPF 3D应用程序中使用MVVM设置此鼠标下载代码?,wpf,mvvm,mouse,Wpf,Mvvm,Mouse,我认为: <UserControl x:Class ... MouseDown="UserControl_MouseDown"> <Viewport3D Name="Viewport" Grid.Column="0"> ... </Viewport3D > </UserControl> 在我的视图模型中,我有: public void OnMouseDown(MouseEventArgs e, Viewport3

我认为:

<UserControl x:Class ... MouseDown="UserControl_MouseDown"> 
    <Viewport3D Name="Viewport" Grid.Column="0">
        ...
    </Viewport3D >
</UserControl>
在我的视图模型中,我有:

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
传递给视图模型中的处理程序。这已经够糟糕的了,但在本例中,我实际上传入了一个控件(a
Viewport3D
),这是在二维和三维之间转换坐标所必需的


关于如何使其与MVVM更加协调,有什么建议吗?

我认为这是一种将MVVM做得太过分的情况。当然,MVVM并没有精确定义,但我认为它是试图将我的应用程序的高级机制和行为与如何使用特定UI技术实现这些机制和行为的细节分离开来(当然,现在只是WPF,但我发现假装还有其他东西很有用)


如果不知道应用程序对鼠标事件的反应,就很难给出具体的建议或意见。根据我所看到的,我认为坐标转换最好留在UI层,然后转换后的坐标将通过方法调用传递给ViewModel。

如果您担心通过将视图对象传递给ViewModel而破坏可测试性,创建一个用于在三维点和二维点之间转换的界面,并将其传递。在代码隐藏中,然后在实现该接口的包装器中传递
Viewport3D
对象


除此之外,我不会担心代码隐藏中的事件处理程序。所有简单的事情都使用绑定,真正棘手的部分使用代码隐藏

我最终使用了MVVM Messenger。因此,鼠标事件在代码隐藏中得到处理,然后它发送事件发生的消息。然后,我的ViewModel可以订阅此消息并接收通知。工作起来很有魅力,并保持一切解耦。

@DanM我们一直采取的方法是,进入ViewModel的逻辑应该在UI主机之外工作。如果要对该特定代码运行测试,它会执行吗?还是会因为没有ViewportInfo而失败?如果失败了,逻辑应该像Daniel建议的那样回到UI。请记住,MVVM的主要优点之一是自动化单元测试。
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;
    }
}