zoukankan      html  css  js  c++  java
  • WPF MVVM从入门到精通7:关闭窗口和打开新窗口

    若是登录成功,我们一般会执行的操作是关闭当前窗口,然后打开一个新的窗口。但为了比较理想地实现MVVM,我们被禁止在ViewModel里面访问View的元素。那我们该如何实现上面的功能呢?

    首先是打开窗口的功能,我们使用的方法是:

    (1)窗口初始化的时候即注册需要访问的新窗口。

    (2)ViewModel在需要打开新窗口时,使用注册过的窗口。

    我们先定义一个WindowManager类:

        using System;
        using System.Collections;
        using System.Windows;
         
        namespace LoginDemo.ViewModel.Common
        {
            /// <summary>
            /// 窗口管理器
            /// </summary>
            public static class WindowManager
            {
                private static Hashtable _RegisterWindow = new Hashtable();
         
                public static void Register<T>(string key)
                {
                    if (!_RegisterWindow.Contains(key))
                    {
                        _RegisterWindow.Add(key, typeof(T));
                    }
                }
         
                public static void Register(string key, Type t)
                {
                    if (!_RegisterWindow.Contains(key))
                    {
                        _RegisterWindow.Add(key, t);
                    }
                }
         
                public static void Remove(string key)
                {
                    if (_RegisterWindow.ContainsKey(key))
                    {
                        _RegisterWindow.Remove(key);
                    }
                }
         
                public static void Show(string key, object VM)
                {
                    if (_RegisterWindow.ContainsKey(key))
                    {
                        var win = (Window)Activator.CreateInstance((Type)_RegisterWindow[key]);
                        win.DataContext = VM;
                        win.Show();
                    }
                }
            }
        }

    代码比较简单,就不解释了。然后我们在LoginWindow的构造函数里添加代码,变成如下所示:

        using LoginDemo.ViewModel.Common;
        using LoginDemo.ViewModel.Login;
        using System.Windows;
         
        namespace LoginDemo
        {
            /// <summary>
            /// LoginWindow.xaml 的交互逻辑
            /// </summary>
            public partial class LoginWindow : Window
            {
                public LoginWindow()
                {
                    InitializeComponent();
         
                    this.DataContext = new LoginViewModel();
         
                    WindowManager.Register<MainWindow>("MainWindow");
                }
            }
        }

    是不是发现这里说好只加一行,现在又加一行代码了?实在没有办法,打开窗口就是要这么做。

    然后我们在ViewModel需要打开窗口的地方写下面一行代码:

    WindowManager.Show("MainWindow", null);

    这样新的窗口就能在ViewModel里面被打开了。

     

    我们接下来说关闭窗口。要做到这一功能,我们又要借助System.Windows.Interacivity里面的Behavior。它可以把ViewModel里面的一个属性,关联到View层的一个事件(我们这里当然是要关联Window.Close())。

    我们先来定义这个关闭行为:

        using System.Windows;
        using System.Windows.Interactivity;
         
        namespace LoginDemo.ViewModel.Common
        {
            /// <summary>
            /// 窗口行为
            /// </summary>
            public class WindowBehavior : Behavior<Window>
            {
                /// <summary>
                /// 关闭窗口
                /// </summary>
                public bool Close
                {
                    get { return (bool)GetValue(CloseProperty); }
                    set { SetValue(CloseProperty, value); }
                }
                public static readonly DependencyProperty CloseProperty =
                    DependencyProperty.Register("Close", typeof(bool), typeof(WindowBehavior), new PropertyMetadata(false, OnCloseChanged));
                private static void OnCloseChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
                {
                    var window = ((WindowBehavior)d).AssociatedObject;
                    var newValue = (bool)e.NewValue;
                    if (newValue)
                    {
                        window.Close();
                    }
                }
         
            }
        }

    然后我们在XAML文件里增加以下内容:

        <i:Interaction.Behaviors>
            <c:WindowBehavior Close="{Binding ToClose}"/>
        </i:Interaction.Behaviors>

    这样的话,窗口的关闭事件就绑定到了ViewModel里面的ToClose属性了。但这个属性还没有呢,定义一个:

        private bool toClose = false;
        /// <summary>
        /// 是否要关闭窗口
        /// </summary>
        public bool ToClose
        {
            get
            {
                return toClose;
            }
            set
            {
                toClose = value;
                if (toClose)
                {
                    this.RaisePropertyChanged("ToClose");
                }
            }
        }

    如此,只要我们在ViewModel里面执行ToClose=true;,当前窗口就会关闭。这节的内容体现在点击登录按钮上,大体如下:

        private BaseCommand loginClick;
        /// <summary>
        /// 登录事件
        /// </summary>
        public BaseCommand LoginClick
        {
            get
            {
                if (loginClick == null)
                {
                    loginClick = new BaseCommand(new Action<object>(o =>
                    {
                        //执行登录逻辑
                        WindowManager.Show("MainWindow", null);
                        ToClose = true;
                    }));
                }
                return loginClick;
            }
        }

  • 相关阅读:
    常见的单链表题目
    一个string类的几个函数
    strcpy和memcpy的区别
    字符串及 strcpy几种写法
    什么函数不能声明为虚函数
    STL中Vector和List的底层数据结构
    C/C++堆、栈及静态数据区详解
    tcp四次握手
    几个知识点
    内存对齐的规则与作用
  • 原文地址:https://www.cnblogs.com/ljdong7/p/12058064.html
Copyright © 2011-2022 走看看