我有一个按钮,我将此按钮绑定(bind)到 ViewModel 中的一个命令,比如 OpenWindowCommand
。当我点击按钮时,我想打开一个新窗口。但是创建一个窗口实例并从 View 模型中显示一个窗口是违反 MVVM 的。我创建了这样的界面
interface IWindowService
{
void showWindow(object dataContext);
}
和WindowService
像这样实现了这个接口(interface)
class WindowService : IWindowService
{
public void showWindow(object dataContext)
{
ChildWindow window=new ChildWindow();
window.DataContext=dataContext;
window.Show();
}
}
在这个类中我指定了ChildWindow
。所以这个类与显示 ChildWindow
紧密耦合。当我想显示另一个窗口时,我必须实现另一个具有相同接口(interface)和逻辑的类。我怎样才能使这个类通用,这样我就可以传递任何窗口的实例,并且该类将能够打开任何窗口?
我没有使用任何内置的 MVVM 框架。我已经阅读了很多关于 StackOverflow 的文章,但我找不到任何解决方案。
最佳答案
您说“创建窗口实例并从 View 模型显示窗口违反了 MVVM”。这是正确的。
您现在正在尝试创建一个采用 VM 指定的 View 类型的界面。这同样是一种违规行为。您可能已经抽象出接口(interface)背后的创建逻辑,但您仍在请求从 VM 内部创建 View 。
VM 应该只关心创建 VM。如果您确实需要一个新窗口来托管新 VM,请像您所做的那样提供一个界面,但不提供 View 。为什么需要 View ?大多数(VM 优先)MVVM 项目使用隐式数据模板将 View 与特定 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>
关于c# - 在 MVVM WPF 中打开新窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25845689/