在MVVM WPF打开新窗口 [英] Opening new window in MVVM WPF
问题描述
我有按钮,我已经绑定这个按钮,在视图模型指挥说OpenWindowCommand。当我点击按钮,我想打开新的窗口。但是创建窗口实例,并表示从视图模型窗口是违反MVVM的。我创建界面像
I have Button and I have bind this button to command in ViewModel say OpenWindowCommand. When I click on button I want to open new window. But creating window instance and showing window from view model is violation of MVVM. I have created interface like
interface IWindowService
{
void showWindow(object dataContext);
}
和WindowService实现像
and WindowService implements this interface like
class WindowService:IWindowService
{
public void showWindow(object dataContext)
{
ChildWindow window=new ChildWindow();
window.DataContext=dataContext;
window.Show();
}
}
在此I类指定ChildWindow。所以这个类是紧密结合显示ChildWindow。当我想显示另一个窗口,我要实现具有相同的接口和logic.How另一个类我可以让这个类通用的,所以我可以传递任何窗口类的实例,只是将能够打开的任何窗口?
我没有使用任何内置MVVM frameworks.I已经阅读StackOverflow上很多文章,但我无法找到此任何解决方案。
In this class I have specified ChildWindow. So this class is tightly coupled with showing ChildWindow. When I want to show another window,I have to implement another class with same interface and logic.How can I make this class generic so that I can pass just instance of any window and class will be able to open any window? I am not using any built MVVM frameworks.I have read many articles on StackOverflow but I could not found any solution for this.
推荐答案
您说创建窗口实例,并表示从视图模型窗口是违反MVVM的。这是正确的。
You say "creating window instance and showing window from view model is violation of MVVM". This is correct.
您正试图创建一个需要由VM指明类型的视图界面。这是一样多的侵犯。你可能已经从虚拟机中抽象出来的界面背后的创作逻辑,但你仍然要求查看作品。
You are now trying to create an interface that takes a type of view specified by the VM. This is just as much of a violation. You may have abstracted away the creation logic behind an interface, but you are still requesting view creations from within the VM.
虚拟机应该只关心创建虚拟机。如果你真的需要一个新的窗口来承载新的虚拟机,然后提供一个界面,你所做的一切,但一个并不需要一个视图。为什么你需要的看法?大多数(VM第一)MVVM项目使用隐式的DataTemplates与特定的虚拟机的视图相关联。虚拟机一无所知他们。
VM's should only care about creating VM's. If you really need a new window to host the new VM, then provide an interface as you have done, but one that does NOT take a view. Why do you need the view? Most (VM first) MVVM projects use implicit datatemplates to associate a view with a particular VM. The VM knows nothing about them.
这样的:
class WindowService:IWindowService
{
public void ShowWindow(object viewModel)
{
var win = new Window();
win.Content = viewModel;
win.Show();
}
}
显然,你需要确保你有你的VM->查看隐含的模板设置在App.xaml中为这个工作。这仅仅是标准的VM第一MVVM。
Obviously you need to make sure you have your VM->View implicit templates set up in app.xaml for this to work. This is just standard VM first 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>
这篇关于在MVVM WPF打开新窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!