如果没有 pattern MVVM,在应用程序中调用新窗口WPF非常简单:
// Обработчик кнопки открытия другого окна
void OpenOtherWindow(object sender, RoutedEventArgs e) {
OtherWindow otherWindow = new OtherWindow();
otherWindow.ViewModel = "ViewModel";
otherWindow.Show();
otherWindow.ShowViewModel();
}
// Другое окно
public partial class OtherWindow : Window {
public string ViewModel { get; set; }
public OtherWindow(){
InitializeComponent();
}
public void ShowViewModel(){
MessageBox.Show(ViewModel);
}
}
假设应该使用按钮和键盘快捷键打开一个新窗口。目前,我能建议的唯一方法是:
MainWindowView.xaml(视图元素)
<Window.CommandBindings>
<CommandBinding Command="local:AutomationCommands.OpenOtherWindow" Executed="OpenOtherWindow_Executed"/>
</Window.CommandBindings>
MainWindowView.xaml.cs
private void OpenOtherWindow_Executed(object sender, ExecutedRoutedEventArgs e) {
OtherWindow otherWindow = new OtherWindow();
otherWindow.ViewModel = "ViewModel";
otherWindow.Show();
otherWindow.ShowViewModel();
}
自动化命令.cs
public static RoutedCommand OpenList = new RoutedCommand("OpenOtherWindow", typeof(AutomationCommands), new InputGestureCollection(){
new KeyGesture(Key.N, ModifierKeys.Control)
});
按照模板的概念MVVM,MainWindowView.xaml.cs里面应该没有太多的逻辑。你能建议什么替代的、更正确MVVM的方法?
更新(竞赛)
几个小时以来,我用不同的语言观看了关于这个主题的不同示例。所有这些要么不完整,因此无法将它们带到工作应用程序中,要么太复杂,因此很难理解并使其适应您的应用程序,在了解您在做什么的同时,如果没有帮助,这是不可能的更有经验的 wpf 开发人员。因此,本次比赛的任务如下:
- 制作一个最小但有效的应用程序,在此基础上可以使某些事情进一步复杂化。
- 没有多余的东西:主屏幕上有两个按钮;一个打开一个普通窗口,另一个打开一个对话框(
WPF老实说,我不明白 c 有什么区别,所以请在你的答案中包含这个解释)。在新窗口中将有一个窗口已成功打开的题词。就是这样,我们不需要标记中的任何其他内容。
- 我们将坚持模式
MVVM,但在这个例子中我们不需要模型。也没有带走,是否有必要ViewModel但以防万一,添加了相应的类。因此,文件组织将是这样的(文件夹Models存在,但它是空的):
- 无需编写迷你框架 - 没有开发经验的人
WPF不会理解它们,因此无法理解使用它们。我们只需要代码来打开窗口(在框架内MVVM- 使用服务)并通知服务关闭窗口。 - 由于该应用程序是最简单的,因此在关闭窗口时不会有任何特殊动作。但是,我要求你添加一个空的方法来处理窗口的关闭,这样随着这个例子的进一步复杂化,在哪里插入这个方法就很清楚了(在这个方法中,例如,保存输入的数据)。
代码片段:
MainWindowView.xamlView -主窗口元素
<Window x:Class="MVVM_OpenNewWindowMinimalExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="350">
<StackPanel>
<Button Content="Открыть обычное дочернее окно" Command="{Binding OpenChildWindow}"/>
<Button Content="Открыть диалоговое окно" Command="{Binding OpenDialogWindow}"/>
</StackPanel>
</Window>
MainWindowView.xaml.cs - 这就是它的backcode名字,对吧?
namespace MVVM_OpenNewWindowMinimalExample.Views {
public partial class MainWindowView : Window {
public MainWindowView() {
InitializeComponent();
}
}
}
应用程序.xaml.cs
namespace MVVM_OpenNewWindowMinimalExample {
public partial class App : Application {
protected override void OnStartup(StartupEventArgs e) {
base.OnStartup(e);
var modelView = new MainWindowView {
DataContext = new MainWindowViewModel()
};
modelView.Show();
}
}
}
链接到 Visual Studio 项目(Yandex 磁盘)。它可能会在比赛结束后的一段时间内变得不可用。




一个非常好的问题。打开新窗口是 MVVM 模式的一个棘手部分。
看。一方面,打开新窗口的决定属于业务逻辑层,即VM。另一方面,VM 无权知道有关 View 的任何信息。结果是矛盾的。
通常这个矛盾是通过创建一个额外的打开窗口的服务来解决的,这个服务是在程序开始时配置的,位于VM和View之间。使用这种方法,VM 代码会创建某种类型的 VM 对象,并要求服务提供显示。服务检查对象的类型,创建所需类型的窗口,并通过将传递的对象设置为 来显示它
DataContext。可以在此处找到实现此方法的示例代码(并查看相关问题)。
您仍然必须实现逻辑以在窗口关闭时通知服务(并可能要求 VM 确认这一点)。
已经编写了一个应用程序来演示使用 MVVM 模式打开和关闭窗口。另外,负责打开窗口的命令绑定了热键(Ctrl-Y——打开第一个窗口,Ctrl-Z——打开第二个窗口) 应用代码在git https://github.com/bakulev/MVVM_OpenNewWindowMinimalExample 应用已经过测试。该代码使用问题服务中描述的技巧,用于在 MVVM 模式的上下文中创建模态和非模态窗口
或者,您可以使用经典的“团队”模式,如此处所示。然后,理想情况下,您可以实现仅视图模型的初始化保留在视图中。