wpfmvvm从入门到精通7:关闭窗口和打开新窗口

lonelyxmas lonelyxmas     2023-03-13     384

关键词:

原文:WPF MVVM从入门到精通7:关闭窗口和打开新窗口

WPF MVVM从入门到精通1:MVVM模式简介

WPF MVVM从入门到精通2:实现一个登录窗口

WPF MVVM从入门到精通3:数据绑定

WPF MVVM从入门到精通4:命令和事件

WPF MVVM从入门到精通5:PasswordBox的绑定

WPF MVVM从入门到精通6:RadioButton等一对多控件的绑定

WPF MVVM从入门到精通7:关闭窗口和打开新窗口

WPF MVVM从入门到精通8:数据验证

完整示例代码下载LoginDemo

若是登录成功,我们一般会执行的操作是关闭当前窗口,然后打开一个新的窗口。但为了比较理想地实现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;
    

?

wpfmvvm从入门到精通8:数据验证(代码片段)

原文:WPFMVVM从入门到精通8:数据验证 WPFMVVM从入门到精通1:MVVM模式简介WPFMVVM从入门到精通2:实现一个登录窗口WPFMVVM从入门到精通3:数据绑定WPFMVVM从入门到精通4:命令和事件WPFMVVM从入门到精通5:PasswordBox的绑... 查看详情

wpfmvvm从入门到精通4:命令和事件(代码片段)

原文:WPFMVVM从入门到精通4:命令和事件 ?WPFMVVM从入门到精通1:MVVM模式简介WPFMVVM从入门到精通2:实现一个登录窗口WPFMVVM从入门到精通3:数据绑定WPFMVVM从入门到精通4:命令和事件WPFMVVM从入门到精通5:PasswordBox的... 查看详情

wpfmvvm从入门到精通6:radiobutton等一对多控件的绑定(代码片段)

原文:WPFMVVM从入门到精通6:RadioButton等一对多控件的绑定 ?WPFMVVM从入门到精通1:MVVM模式简介WPFMVVM从入门到精通2:实现一个登录窗口WPFMVVM从入门到精通3:数据绑定WPFMVVM从入门到精通4:命令和事件WPFMVVM从入门到... 查看详情

wpfmvvm从入门到精通2:实现一个登录窗口

我们究竟要做一个怎样的东西呢?直接上图:这看起来比较简单,但把这个登录窗口做完,MVVM的入门就基本完成了。(为什么登录界面要选择性别这么奇怪?无非是因为RadioButton的绑定也是一个课题)很多教程都是举一个小例子... 查看详情

如何从作为wpfmvvm模式中的窗口打开的视图模型中关闭用户控件?(代码片段)

...,所以如果有人可以请我提供一些适当的例子,因为我对wpfMVVM模式相当新。viewmodel中的mainwindow按钮命令:privatevoidExecuteOtherMethod(objectparameter)registerWindowwin=(registerWindow)Application.Current.MainWindow;//win.pp.IsOpen=true;win.bankRectangle.Visibility... 查看详情

winform中关闭退出和打开新窗口的几种方式

关闭窗口,退出的两种方式:1.this.Close();//关闭当前窗口2.Application.Exit();//关闭所有窗口,退出应用程序 打开窗口的三种方式:1.从一个窗口打开另一个窗口新窗口对象.show()2.从一个窗口打开另一个对话框新窗口对象.showDialog(... 查看详情

selenium用法详解从入门到实战java爬虫(代码片段)

目录简介selenium安装java使用 浏览器控制修改窗口大小 窗口最大化 窗口全屏显示浏览器前进&后退浏览器刷新浏览器打开新标签页 浏览器窗口切换关闭标签页关闭浏览器浏览器页面截图其他操作 简介  Selenium是一个用于Web... 查看详情

wpfmvvm从入门到精通3:数据绑定

我们前面已经说过,现在后端和前端可以分头行事了。我们先来看看后端要做的事情。对应于用户名输入框,ViewModel里面应该有一个相应的对象。当这个对象状态发生改变时,需要向View发出一个通知。因为所有的属性都要做这... 查看详情

wpfmvvm从入门到精通4:命令和事件

这一部分我们要做的事情,是把点击登录按钮的事件也在ViewModel里实现。若不是用MVVM模式,可能XAML文件里是这样的:<ButtonGrid.Row="3"Grid.ColumnSpan="2"Content="登录"Width="200"Height="30"Click="Button_Click"/>而跟XAML文件相关的CS文件里则... 查看详情

flink从入门到精通系列文章

戳更多文章:1-Flink入门2-本地环境搭建&构建第一个Flink应用3-DataSetAPI4-DataSteamAPI5-集群部署6-分布式缓存7-重启策略8-Flink中的窗口9-Flink中的TimeFlink时间戳和水印Broadcast广播变量FlinkTable&SQLFlink实战项目实时热销排行Flink写入Red... 查看详情

mysql数据库从入门到精通第2讲启动停止连接

MySQL数据库的初步使用在上一小节我们已经简单了解了数据库与一些相关概念没看上一节的同学戳这里MySQL安装手册接下来我们来学习下如何使用一下MySQL1MySQL的启动MySQL服务是随着电脑开机自动启动的,在windows中MySQL的服务... 查看详情

检查打开的窗口是不是已关闭

】检查打开的窗口是不是已关闭【英文标题】:Checkifopenedwindowhasbeenclosed检查打开的窗口是否已关闭【发布时间】:2012-08-2409:28:52【问题描述】:我有一个主窗口,即应用程序启动窗口。在该窗口中,有一个绑定到SQLDatabase的Repea... 查看详情

用python2.7编的小游戏

...到了相关教程。自己用google搜:用Python和Pygame写游戏-从入门到精通(目录)就可以找到了。其是一系列的帖子:系统学习部分用Python和Pygame写游戏-从入门到精通(1)Pygame的历史,安装Pygame,第一个Pygame脚本用Python和Pygame写游戏... 查看详情

java如何关闭当前窗口打开新的窗口

新的窗口的打开,和打开第1个窗口一样,new、setVisible关闭当前的,可以使用dispose参考技术A直接调用新窗口的setVisible(false);方法就可以了。本回答被提问者和网友采纳 查看详情

selenium对浏览器标签页进行关闭和切换(代码片段)

关闭标签页#1.关闭浏览器全部标签页driver.quit()#2.关闭当前标签页(从标签页A打开新的标签页B,关闭标签页A)driver.close() 切换标签页fromseleniumimportwebdriverbrowser=webdriver.Firefox()browser.get(‘xxxxx‘)#获取当前窗口句柄(窗口A)hand... 查看详情

在 PyQt5 中打开一个窗口和关闭一个窗口

】在PyQt5中打开一个窗口和关闭一个窗口【英文标题】:OpenawindowandcloseawindowinPyQt5【发布时间】:2017-08-1621:28:21【问题描述】:我正在尝试从欢迎屏幕加载一个带有UI窗口的新类,同时关闭欢迎屏幕。当我单击按钮打开新窗口时... 查看详情

unitymemoryprofiler从入门到精通

前言:UnityMemoryProfiler主要用来查看托管内存和本机内存的详细分配情况。它通过捕获、检查、比对内存快照的方式来检测内存泄漏和内存碎片。本篇文章中使用的版本是0.2.10版本。打开偏好设置:点击【Preferences->Analys... 查看详情

wpfmvvm从入门到精通1:mvvm模式简介

刚开始接触和使用MVVM模式的时候,就有一种感觉:哇,实现这么一丁点的功能,竟然要写这么多代码,太麻烦了吧!但是后来当我熟悉了这种模式之后,感觉就变成了:哇,还是这么麻烦。没错,使用MVVM模式的确要在项目中增... 查看详情