我有一个Button,并将此按钮绑定到ViewModel中的一条命令say OpenWindowCommand。当我单击按钮时,我想打开一个新窗口。但是创建窗口实例并从视图模型显示窗口是违反MVVM的。我已经创建了界面
OpenWindowCommand
interface IWindowService { void showWindow(object dataContext); }
并WindowService实现此接口,例如
WindowService
class WindowService : IWindowService { public void showWindow(object dataContext) { ChildWindow window=new ChildWindow(); window.DataContext=dataContext; window.Show(); } }
在课堂上我指定了ChildWindow。因此,这堂课与表演紧密结合ChildWindow。当我想显示另一个窗口时,必须使用相同的接口和逻辑来实现另一个类。如何使该类通用,以便我可以传递任何窗口的实例,并且该类将能够打开任何窗口?
ChildWindow
我没有使用任何内置的MVVM框架。我已经阅读了许多关于StackOverflow的文章,但是找不到任何解决方案。
您说“从视图模型创建窗口实例并显示窗口违反了MVVM”。这是对的。
现在,您正在尝试创建一个接口,该接口采用VM指定的视图类型。这同样违反。您可能已经抽象出了界面背后的创建逻辑,但是您仍在从VM内部请求视图创建。
VM仅应关心创建VM。如果您确实需要一个新窗口来托管新VM,则可以像完成操作一样提供一个界面,但不提供视图。为什么需要视图?大多数(VM首先)MVVM项目使用隐式数据模板将视图与特定VM关联。VM对它们一无所知。
像这样:
class WindowService:IWindowService { public void ShowWindow(object viewModel) { var win = new Window(); win.Content = viewModel; win.Show(); } }
显然,您需要确保在app.xaml中设置了VM-> View隐式模板,才能正常工作。这只是标准VM首先的MVVM。
例如:
<Application x:Class="My.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vm="clr-namespace:My.App.ViewModels" xmlns:vw="clr-namespace:My.App.Views" StartupUri="MainWindow.xaml"> <Application.Resources> <DataTemplate DataType="{x:Type vm:MyVM}"> <vw:MyView/> </DataTemplate> </Application.Resources> </Application>