【问题标题】:Closing window in ViewModel in WPF MVVM在 WPF MVVM 中的 ViewModel 中关闭窗口
【发布时间】:2016-09-04 12:34:12
【问题描述】:

我有一个带有一些内部代码的 ViewModel,需要关闭我的 viewmodel 绑定到的窗口。到目前为止,我有:

MyWindow.xaml.cs

public class MyWindow : Window
{
    public MyWindow()
    {
        InitializeComponent();

        DataContext = new MyVM(this);
    }
}

MyVM.cs

public class MyVM
{
    public MyVM(MyWindow owner)
    {
        Owner = owner;
    }

    public MyWindow Owner { get; }

    public void SomeAction()
    {
        Owner.Close();
    }
}

这很好用,但是我在 MyVM 和 My Window 之间创建了一个不需要的依赖关系,或者至少不是有意的。

所以这是我的问题:有没有办法关闭窗口而不直接将窗口的引用传递给视图模型?

更新 - Possible Duplicate:

问题和接受的答案不同,我没有任何命令绑定,我无法将窗口作为命令参数传递。

可能的重复问题显示一些 vm 代码作为命令绑定到按钮。我不想在命令绑定范围内执行 Window.Close()。

【问题讨论】:

  • 要解耦 V 和 VM,您可以使用 Command 和 EventAggregator。
  • 您可以在您的 MVVM 中生成一个您将在 View 中订阅的事件。
  • 你能告诉我怎么做吗?
  • @JonnyPiazzi 有大约 400-5000 篇关于这个场景的教程/博客文章

标签: c# .net wpf xaml mvvm


【解决方案1】:

如果您使用框架,他们通常有一个消息系统,可以广播消息以供整个程序收听。一个简单的系统有一个关闭窗口消息,该消息被广播并且只被窗口监听,因此允许视图模型广播他们想要关闭窗口,并且只有他们的窗口接收它。

在 MVVMLight 网站上,有一个关于使用他们的 Messenger 系统安全关闭应用程序的博客,允许应用程序的所有部分在关闭之前正确清理:

http://blog.galasoft.ch/posts/2009/10/clean-shutdown-in-silverlight-and-wpf-applications/

【讨论】:

    【解决方案2】:

    在 MVVM 中,ViewModel 不应该知道任何 UI 类,更不用说知道它链接到的特定 View 对象。

    对于完全解耦的解决方案,您可以在 View 窗口上创建附加属性,然后可以将其绑定到 ViewModel 上的适当属性。 this question 的评分最高的答案有详细信息。

    如果您想将此方法应用于非模态窗口和模态窗口,则需要对这段代码进行小幅调整。

    private static void DialogResultChanged(DependencyObject target, DependencyPropertyChangedEventArgs args)
    {
        var window = target as Window;
    
        if (window == null)
            return;
    
        if (window.IsModal())
            window.DialogResult = args.NewValue as bool?;
        else
            window.Close();
    }
    

    其中 IsModel() 被定义为 Window 扩展方法

    public static class WindowExtender
    {
        public static bool IsModal(this Window window)
        {
            var fieldInfo = typeof(Window).GetField("_showingAsDialog", BindingFlags.Instance | BindingFlags.NonPublic);
            return fieldInfo != null && (bool)fieldInfo.GetValue(window);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-09
      • 1970-01-01
      • 2020-09-04
      • 2015-04-09
      • 1970-01-01
      • 2011-05-27
      相关资源
      最近更新 更多