RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 727749
Accepted
Боков Глеб
Боков Глеб
Asked:2020-10-07 16:14:39 +0000 UTC2020-10-07 16:14:39 +0000 UTC 2020-10-07 16:14:39 +0000 UTC

WPF:从 MVVM 概念的角度来看,用命令调用新窗口的正确方法是什么?

  • 772

如果没有 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 磁盘)。它可能会在比赛结束后的一段时间内变得不可用。

c#
  • 3 3 个回答
  • 10 Views

3 个回答

  • Voted
  1. VladD
    2020-10-07T17:34:21Z2020-10-07T17:34:21Z

    一个非常好的问题。打开新窗口是 MVVM 模式的一个棘手部分。

    看。一方面,打开新窗口的决定属于业务逻辑层,即VM。另一方面,VM 无权知道有关 View 的任何信息。结果是矛盾的。

    通常这个矛盾是通过创建一个额外的打开窗口的服务来解决的,这个服务是在程序开始时配置的,位于VM和View之间。使用这种方法,VM 代码会创建某种类型的 VM 对象,并要求服务提供显示。服务检查对象的类型,创建所需类型的窗口,并通过将传递的对象设置为 来显示它DataContext。

    可以在此处找到实现此方法的示例代码(并查看相关问题)。


    您仍然必须实现逻辑以在窗口关闭时通知服务(并可能要求 VM 确认这一点)。

    • 12
  2. Best Answer
    Anton Bakulev
    2020-10-13T15:17:57Z2020-10-13T15:17:57Z

    已经编写了一个应用程序来演示使用 MVVM 模式打开和关闭窗口。另外,负责打开窗口的命令绑定了热键(Ctrl-Y——打开第一个窗口,Ctrl-Z——打开第二个窗口) 应用代码在git https://github.com/bakulev/MVVM_OpenNewWindowMinimalExample 应用已经过测试。该代码使用问题服务中描述的技巧,用于在 MVVM 模式的上下文中创建模态和非模态窗口

    • 7
  3. Streletz
    2020-10-07T17:02:26Z2020-10-07T17:02:26Z

    或者,您可以使用经典的“团队”模式,如此处所示。然后,理想情况下,您可以实现仅视图模型的初始化保留在视图中。

    • 1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    Python 3.6 - 安装 MySQL (Windows)

    • 1 个回答
  • Marko Smith

    C++ 编写程序“计算单个岛屿”。填充一个二维数组 12x12 0 和 1

    • 2 个回答
  • Marko Smith

    返回指针的函数

    • 1 个回答
  • Marko Smith

    我使用 django 管理面板添加图像,但它没有显示

    • 1 个回答
  • Marko Smith

    这些条目是什么意思,它们的完整等效项是什么样的

    • 2 个回答
  • Marko Smith

    浏览器仍然缓存文件数据

    • 1 个回答
  • Marko Smith

    在 Excel VBA 中激活工作表的问题

    • 3 个回答
  • Marko Smith

    为什么内置类型中包含复数而小数不包含?

    • 2 个回答
  • Marko Smith

    获得唯一途径

    • 3 个回答
  • Marko Smith

    告诉我一个像幻灯片一样创建滚动的库

    • 1 个回答
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Алексей Шиманский 如何以及通过什么方式来查找 Javascript 代码中的错误? 2020-08-03 00:21:37 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5