【问题标题】:MVVM Window / Control OperationsMVVM 窗口/控制操作
【发布时间】:2010-08-26 19:53:01
【问题描述】:

我正在构建一个 WPF MVVM 应用程序,并且我想保留我可以符合 MVVM 的内容(我知道有些东西是过度设计的,但在这里尽最大努力)。

我遇到了一个小难题,我需要根据视图模型中的方法中的一些逻辑隐藏/关闭窗口。

我这辈子都想不出一个可靠的方法来做到这一点。我已将 Visibility 属性绑定到窗口的 Visibility DP,该属性有效(排序),但我如何在对话框中调用 Close()

我正在使用 View-First MVVM,因此视图模型不了解视图,视图实例化了一个视图模型(通过 DI/IoC)并将其设置为 DataContext。

命令以错误的方式工作,事件是不可能的,除非我在代码中绑定到它,如果有一个不完全复杂的 MVVM 方式来做到这一点,那是 id 而不是做的事情。

来自更大的 SO 社区的任何想法?

或者也许我总体上缺少关于 MVVM 的一些东西?无论哪种方式,请告诉我:o

【问题讨论】:

    标签: .net wpf mvvm


    【解决方案1】:

    通常情况下,有很多方法可以给这只猫剥皮。

    在视图中不使用代码隐藏的一种方法是使用附加行为,例如:

    public static class CloseBehavior 
    {
        public static bool GetCloseWhen(DependencyObject obj)
        {
            return (bool)obj.GetValue(CloseWhenProperty);
        }
    
        public static void SetCloseWhen(DependencyObject obj, bool value)
        {
            obj.SetValue(CloseWhenProperty, value);
        }
    
        public static readonly DependencyProperty CloseWhenProperty =
            DependencyProperty.RegisterAttached(
                "CloseWhen", typeof(bool), typeof(CloseBehavior), 
                new UIPropertyMetadata(OnCloseWhenChanged));
        // the lone parameter in the UIPropertyMetadata is a callback
        // for when the property value changes
    
        static void OnCloseWhenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            // if false, we're not concerned with it
            if(!(bool)e.NewValue) return;
    
           // if attached to something other than a window, this doesn't make sense
            var win = d as Window;
    
            if(d == null) return;
    
                // close the window
            win.Close();
        }
    }
    

    在您的 XAML 中:

    <Window x:Class="WpfApplication1.Window1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
         xmlns:local="clr-namespace:WpfApplication1" 
    
         local:CloseBehavior.CloseWhen="{Binding ViewModelWorkComplete}"
    >
    <! -- content -->
    </Window>
    

    ViewModelWorkComplete 只是视图模型中的布尔属性。

    效果是当视图模型将ViewModelWorkComplete 设置为true(并引发相应的INotifyPropertyChanged 事件)时,窗口将关闭。

    【讨论】:

    • 哦,我喜欢这个想法,这就像我已经在做的相反的事情,将窗口事件绑定到我的视图模型上的命令中。 +1
    【解决方案2】:

    事件和订阅代码隐藏有什么问题?关闭窗口是特定于演示的事情,它当然属于视图。

    这里的主要目标是可测试性和关注点分离,您可以轻松验证特定事件是由 ViewModel 引发的。

    【讨论】:

      【解决方案3】:

      使用中介者模式或其他事件处理机制,您可以引发某些视图模型事件(可能是“SaveDone”或“NoDataRemaining”等)。然后让你的视图监听这些事件;基于它们,窗口可以决定自行关闭。

      如果有更明确的方式让用户说“关闭”(例如通过单击窗口中的关闭按钮),希望可以在窗口中独占处理。

      【讨论】:

      • 是的,关闭视图是一个合乎逻辑的决定。不是用户定义的。中介者模式可能是解决这个问题的最佳方式,但 Dmitry 认为这是一个特定于演示的问题,对你们俩都 +1。
      猜你喜欢
      • 2011-12-09
      • 1970-01-01
      • 2014-02-18
      • 1970-01-01
      • 2015-04-09
      • 2010-12-16
      • 2021-06-29
      • 1970-01-01
      • 2016-08-31
      相关资源
      最近更新 更多