在使用MVVM模式时,控制Windows的方式

27 浏览
0 Comments

在使用MVVM模式时,控制Windows的方式

前段时间,我写了这篇Stack Overflow帖子,寻找一种处理UI和业务层交互的良好方法。我喜欢一个回答,建议使用MVVM模式。于是我按照这个模式成功地进行了开发,但是在使用这个模式的过程中遇到了一个问题。事实上,在我的UI的某个部分,一个按钮应该打开一个包含在ListView中显示的项目的详细信息的对话框。

我看到了这个Stack Overflow帖子问到了同样的问题,但是我没有完全理解答案,我想知道这个答案是否适用于我的情况。答案的主意是使用Unity框架,并通过App.Container.Resolve().ShowDialog()来调用与视图关联的窗口,例如。

然而,我的问题是我把ViewModels实现在了与UI客户端项目分离的项目中。我这样做是为了在项目的后期,如果需要,可以从其他客户端使用这些ViewModels。第一个问题是,这样的模式实现是否错误?

第二个问题是,由于我的ViewModels项目实际上不在客户端项目中,因此我无法访问App全局变量。所以我认为我无法使用我在前面提到的解决方案。是否有任何解决方法?

0
0 Comments

问题的出现原因是在使用MVVM模式时,控制WPF窗口的方法不够合适,不能在ViewModel中引用App类。解决方法是考虑将适当的UnityContainer注入到ViewModel中,如果无法注入容器,则可以考虑添加一个Controller或使用中介者模式。

在实现时,可以将UI、VM和模型分别放在不同的程序集中。可以将App视为“UI类”,将其作为UI类处理。可以通过将适当的UnityContainer注入到ViewModel中来解决问题。如果无法注入容器,可以考虑在解决方案中添加一个Controller类或使用其他答案中在提到的Mediator模式。

在另一个帖子中讨论时,有人认为使用Controller会“破坏”MVVM模式,只要将视图的引用传递给ViewModel就会出现这种情况。但我不同意Controller会破坏MVVM。通常,我会在UI程序集中添加一个Controller类,该类实现了一个接口(在VM程序集或公共程序集中定义的IController接口)。我的ViewModels会注入一个IController。不要公开Controller上的任何成员,以避免对UI程序集的依赖。例如,不要公开一个MyChildView成员,而是公开一个执行所需工作的方法。

如果需要在解耦方面更加极端,不喜欢与具体的UI类耦合的Controller,可以考虑在视图上实现接口。在ViewModel或Controller中执行_injectedContainter.Resolve<IAnyChildView>().ShowDialog()是没有问题的。

0
0 Comments

问题的出现原因:

在使用MVVM模式的WPF应用程序中,控制窗口的显示和关闭可能会导致一些困扰。传统的方法是在视图模型中直接引用视图,并在视图模型中处理窗口的显示和关闭操作。然而,这与MVVM模式的原则相悖,因为视图模型应该与视图解耦,不应该直接引用视图。

解决方法:

一种解决方法是使用新的线程来初始化和显示窗口,并将该线程转换为UI线程。可以使用Dispatcher.Run()方法将线程转换为UI线程,并且该方法会一直阻塞直到窗口关闭。在Dispatcher.Run()之后,可以根据需要处理对话框的结果。

代码实现如下:

new Thread(() =>
{
    MyDialogWindow m = new MyDialogWindow();
    m.ShowDialog();
    Dispatcher.Run();
    // Handle dialog result here.
}).Start();

此外,还需要为关闭窗口添加一个事件,以便停止Dispatcher。可以在对话框的构造函数中添加以下代码:

Closed += (_,__) => Dispatcher.InvokeShutdown();

但是,这样做意味着从视图模型中引用视图,这与MVVM模式的原则相悖。为了解决这个问题,可以创建一个单独的类来处理窗口的显示和关闭操作,并从该类中返回对话框窗口的值。

文章如上所述,是关于在使用MVVM模式的WPF应用程序中控制窗口的显示和关闭的问题的原因和解决方法的概述。

0