如何在我的 WPF 3D 应用程序中对这个 MouseDown 代码进行 MVVM 化?

发布于 2024-09-03 02:35:24 字数 1200 浏览 2 评论 0原文

在我看来,我有:

<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 更加协调有什么建议吗?

In my view, I have:

<UserControl x:Class ... MouseDown="UserControl_MouseDown"> 
    <Viewport3D Name="Viewport" Grid.Column="0">
        ...
    </Viewport3D >
</UserControl>

In my code-behind, I have:

private void UserControl_MouseDown(object sender, MouseButtonEventArgs e)
{
    ((MapPanelViewModel)DataContext).OnMouseDown(e, Viewport);
}

And in my view-model, I have:

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;
    }
}

I really don't have a good sense of how to handle mouse events with MVVM. I always just end up putting them in the code-behind and casting the DataContext as SomeViewModel, then passing the MouseEventArgs on to a handler in my view-model. That's bad enough already, but in this case, I'm actually passing in a control (a Viewport3D), which is necessary for translating coordinates between 2D and 3D.

Any suggestions on how to make this more in tune with MVVM?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浊酒尽余欢 2024-09-10 02:35:24

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

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

I think this is a case of taking MVVM too far. MVVM is not precisely defined, of course, but I think of it in terms of trying to separate my applications high-level mechanics and behaviors from the details of how those mechanics and behaviors get implemented using a particular UI technology (it's just WPF these days, of course, but I find it useful to pretend there might be something else).

Without knowing how your application is supposed to react to the mouse events, it's hard to give specific advice or opinion. Based on what I do see, I think the coordinate translation is best left in the UI layer and then the translated coordinates would get passed to the ViewModel via a method call.

孤千羽 2024-09-10 02:35:24

如果您担心将 View 对象传递到 ViewModel 会破坏可测试性,请创建一个用于在 3D 和 2D 点之间进行转换的接口并传递该接口。然后,在后面的代码中,将 Viewport3D 对象传递到实现该接口的包装器中。

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

If you are worried about breaking testability by passing a View object through to your ViewModel, create a interface for converting between 3D and 2D points and pass that through instead. In your code behind, you then pass the Viewport3D object through in a wrapper which implements that interface.

Other than that I wouldn't worry about the event handlers in code behind. Use bindings for everything that is easy, use the code behind for the really tricky parts.

网名女生简单气质 2024-09-10 02:35:24

我最终使用了 MVVM Messenger。因此,鼠标事件在后面的代码中得到处理,然后发送一条事件发生的消息。然后,我的 ViewModel 可以订阅此消息并接收通知。工作起来就像一个魅力,让一切都解耦。

I ended up using the MVVM Messenger. So, the mouse event gets handled in the code behind, then it sends a message that the event occurred. Then, my ViewModel can subscribe to this message and receive notification. Works like a charm and keeps everything decoupled.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文