WPF MVVM从入门到精通7:关闭窗口和打开新窗口
WPF MVVM从入门到精通5:PasswordBox的绑定
WPF MVVM从入门到精通6:RadioButton等一对多控件的绑定
若是登录成功,我们一般会执行的操作是关闭当前窗口,然后打开一个新的窗口。但为了比较理想地实现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;
}
}
WPF MVVM从入门到精通7:关闭窗口和打开新窗口的更多相关文章
- WPF MVVM从入门到精通8:数据验证
原文:WPF MVVM从入门到精通8:数据验证 WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录窗口 WPF MVVM从入门到精通3:数据绑定 WPF M ...
- WPF MVVM从入门到精通6:RadioButton等一对多控件的绑定
原文:WPF MVVM从入门到精通6:RadioButton等一对多控件的绑定 WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录窗口 WPF MVVM ...
- WPF MVVM从入门到精通5:PasswordBox的绑定
原文:WPF MVVM从入门到精通5:PasswordBox的绑定 WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录窗口 WPF MVVM从入门到精通 ...
- WPF MVVM从入门到精通3:数据绑定
原文:WPF MVVM从入门到精通3:数据绑定 WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录窗口 WPF MVVM从入门到精通3:数据绑定 WPF ...
- WPF MVVM从入门到精通4:命令和事件
原文:WPF MVVM从入门到精通4:命令和事件 WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录窗口 WPF MVVM从入门到精通3:数据绑定 WP ...
- WPF MVVM从入门到精通2:实现一个登录窗口
原文:WPF MVVM从入门到精通2:实现一个登录窗口 WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录窗口 WPF MVVM从入门到精通3:数据绑定 ...
- WPF MVVM从入门到精通1:MVVM模式简介
原文:WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录窗口 WPF MVVM从入门到精通3:数据绑定 W ...
- WPF/MVVM Quick Start Tutorial - WPF/MVVM 快速入门教程 -原文,翻译及一点自己的补充
转载自 https://www.codeproject.com/articles/165368/wpf-mvvm-quick-start-tutorial WPF/MVVM Quick Start T ...
- 打开新窗口(window.open)关闭窗口(window.close)
打开新窗口(window.open) open() 方法可以查找一个已经存在或者新建的浏览器窗口. 语法: window.open([URL], [窗口名称], [参数字符串]) 参数说明: URL: ...
随机推荐
- 【CSS】iconfont的使用
说到浏览器对@font-face的兼容问题,这里涉及到一个字体format的问题,因为不同的浏览器对字体格式支持是不一致的,这样大家有必要了解一下,各种版本的浏览器支持什么样的字体,前面也简单带到了有 ...
- 8、Dubbo-配置(3)
高可用 1.zookeeper宕机与dubbo直连 现象:zookeeper注册中心宕机,还可以消费dubbo暴露的服务. 原因: 健壮性 监控中心宕掉不影响使用,只是丢失部分采样数据 数据库宕掉后, ...
- Java50道经典习题-程序23 求岁数
题目:有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁.问第4个人岁数,他说比第3个人大2岁.问第三个人,又说比第2人大两岁.问第2个人,说比第1个人大两岁.最后问第一个人,他说是10岁.请问 ...
- [Python 多线程] 详解daemon属性值None,False,True的区别 (五)
本文以多个例子介绍Python多线程中daemon属性值的区别. 回顾: 前面的文章简单介绍了在现代操作系统中,每一个进程都认为自己独占所有的计算机资源. 或者说线程就是独立的王国,进程间是相对独立的 ...
- spring boot 2.x拦截器导致静态资源404终极解决办法
首先添加application文件static路径,我的是yml文件 spring: mvc: static-path-pattern: /static/**然后注册拦截器类如下方法; @Overri ...
- 每天to do list
至少写一页书 写代码做一个实验 读10+页专业书 一年时间,如果经济状况没有改善的话,回归企业.
- 聊聊编程开发的数据库批量插入(sql)
这里的批量插入,主要是支持SQL的大型存储数据库,本文以Mysql,Oracle,SqlServer,postgresql4类来说明,这大概是国内应用比较多的了.其余的应该可以按照这些去找.提到编程的 ...
- Eclipse部署Web项目,常用操作和常见错误的解决方案
部署Web项目到tomcat 在eclipse中找到Servers项,打开服务器(F3)(建议直接删除服务器,重新建立再设置比较好)1.Servers Locations 中选择Use Tomcat ...
- Java编程基础知识总结大全(Ⅰ)
Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承.指针等概念,因此Java语言具有功能强大和简单易用两个特征.Java语言作为静态面向对象编程语言的代表 ...
- C++较精确的测试代码运行时间
#include <chrono> using namespace chrono; int main() { auto t0 = system_clock::now(); //测试代码 a ...