离上一篇WPF随笔有多久,再度编码WPF项目就有多久。机缘巧合又接下了一个开发WPF桌面程序的任务,又有机会详细研究之前一直忽略的细节。
今天就来谈谈如何在MVVM模式下关闭窗口。
什么?关闭窗口还要写代码?点个×不就行了?
起初我也是这么想的, 然而实践证明并没有那么简单。


1.需求场景描述

在主窗口(一般默认是MainWindow)打开子窗口ChildWindow,在子窗口中进行数据的新增或编辑操作,点击自定义的“保存”按钮,在数据保存完成后自动关闭当前子窗口。
需求非常简单,如果使用路由事件那将会非常简单。但使用MVVM模式就意味着View视图层与ViewModel视图模型层的分离,直接添加路由事件不太现实。

2.解决方案

通用的解决方案有很多,网上一搜一大堆,大体思路都一样。结合MVVM模式的思想和WPF的自身特性,一是从Binding绑定着手,二是不能在xaml.cs里写路由事件就在ViewModel里实现路由事件。

2.1 从绑定着手

子窗口ChildWindow的xaml代码片段

<Button Command="{Binding SaveCommand}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Window}}}"><Button.ContentTemplate><DataTemplate><StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center"><icon:PackIconModern Width="12" Height="12" HorizontalAlignment="Center" VerticalAlignment="Center" Kind="Save"></icon:PackIconModern><TextBlock Margin="3,0,0,0">保存</TextBlock></StackPanel></DataTemplate></Button.ContentTemplate>
</Button>

其中绑定参数CommandParameter是重点,表达式的含义是找到当前的窗口。

ViewModel层ChildViewModel.cs的命令定义:

 //保存命令,传递参数为窗口类型public DelegateCommands<System.Windows.Window> SaveCommand { get; set; }

ChildViewModel.cs的命令对应方法实现

 private async void Save(System.Windows.Window obj){//////你的业务逻辑代码///var win = obj;win.Close();}

2.2 从路由事件着手

MVVM模式下在xaml.cs里面写路由事件那味道就不对了,但是ViewModel层也可以写代码实现路由事件。
ChildViewModel.cs里的代码片段:

public ChildViewModel()
{//你的初始化代码System.Windows.EventManager.RegisterClassHandler(typeof(System.Windows.Controls.Button), System.Windows.Controls.Button.ClickEvent, new System.Windows.RoutedEventHandler(SaveButtonClicked));}private void SaveButtonClicked(object sender, RoutedEventArgs e)
{///你的业务逻辑代码System.Windows.Controls.Button btn = (System.Windows.Controls.Button)e.Source;var win = FindVisualParent<Window>(btn)[0];win.Close();
}

其中通过可视化数据查找指定父级元素的方法为:

/// 利用VisualTreeHelper寻找指定依赖对象的父级对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static List<T> FindVisualParent<T>(DependencyObject obj) where T : DependencyObject
{try{List<T> TList = new List<T> { };DependencyObject parent = VisualTreeHelper.GetParent(obj);if (parent != null && parent is T){TList.Add((T)parent);List<T> parentOfParent = FindVisualParent<T>(parent);if (parentOfParent != null){TList.AddRange(parentOfParent);}}else if (parent != null){List<T> parentOfParent = FindVisualParent<T>(parent);if (parentOfParent != null){TList.AddRange(parentOfParent);}}return TList;}catch (Exception){return null;}
}

注重小细节,掌握大知识

WPF随笔(十四)--如何在MVVM模式下关闭窗口相关推荐

  1. wpf mvvm模式下CommandParameter传递多参

    wpf mvvm模式下CommandParameter传递多参 原文:wpf mvvm模式下CommandParameter传递多参 CommandParameter一般只允许设置一次,所以如果要传递 ...

  2. C# WPF MVVM模式下在主窗体显示子窗体并获取结果

    01 - 前言 在winform中打开一个新的子窗体很简单,直接实例化窗体并show一下就可以: Form2 f2 = new Form2();f2.Show(); 或者 Form2 f2 = new ...

  3. 云计算设计模式(二十四)——仆人键模式

    云计算设计模式(二十四)--仆人键模式 使用一个令牌或密钥,向客户提供受限制的直接訪问特定的资源或服务,以便由应用程序代码卸载数据传输操作. 这个模式是在使用云托管的存储系统或队列的应用中特别实用,而 ...

  4. WPF MVVM模式下的无阻塞刷新

    MVVM模式下的无阻塞刷新的两种方法: //传统模式下的无刷新调用(主线程开新线程,新线程又调用主线程来更新UI) //第1步先在线程内部计算出需要绑定的数据 //第2步然后再使用Invoke/Beg ...

  5. Linux的基本学习(十四)——进程管理(下)与SELinux

    Linux的基本学习(十四)--进程管理(下)与SELinux 前言 进程这部分内容真是不少,来,我们继续跟着鸟哥学习. 特殊文件与进程 具有SUID/SGID权限的命令执行状态 SUID的权限其实与 ...

  6. MVVM模式下 DataTemplate 中控件的绑定

    今天给ListBox中通过DataTemplate生成的Button绑定命令时,一开始Button始终找不到绑定的命令.现找到了正确的绑定方式,特来记录一下. 先上个正确的示例: <ListBo ...

  7. MVVM模式下实现拖拽

    MVVM模式下实现拖拽 原文:MVVM模式下实现拖拽 在文章开始之前先看一看效果图 我们可以拖拽一个"游戏"给ListBox,并且ListBox也能接受拖拽过来的数据, 但是我们不 ...

  8. java lifo 队列_java - 如何在LIFO模式下实现链接的阻塞队列 - SO中文参考 - www.soinside.com...

    如何在LIFO模式下实现链接的阻塞队列 问题描述 投票:0回答:1 标题已经说明了一切,在我的代码中,我有一个实现链接阻止队列并提供在队列中插入和获取元素的方法的对象,我希望从队列中进行插入/提取. ...

  9. c语言int型等长输出,c语言先程序设计15第十四讲第六章下.ppt

    c语言先程序设计15第十四讲第六章下 高级语言程序设计 主讲教师:贾彩燕 计算机与信息技术学院 计算机科学与技术系 cyjia@ 第六章 数组 主要内容 数组的概念.定义和使用 数组程序实例 数组作为 ...

最新文章

  1. 19.04.27--作业 打字游戏
  2. TOP (100) PERCENT
  3. vue.js中mock本地json数据
  4. traceroute命令的用法实例
  5. java单车吧_暑假一个月,撸个共享单车后台
  6. ActiveMQ此例简单介绍基于docker的activemq安装与集群搭建
  7. 单片机毕业设计196例
  8. 独立游戏人:像素风格游戏制作分享(转)
  9. 在线LaTeX公式编辑器(备忘)
  10. 技术管理角度看C++游戏程序员发展
  11. Python 算法交易实验41 GMM简单估计
  12. 安装智能陈桥五笔时请小心
  13. 我,48岁高管,失业2年找不到工作:职场中年,还有上坡路吗?
  14. 产品读书.心理学《梦的解析》
  15. 中学计算机课外小组活动计划,小学数学课外活动计划
  16. 《需求工程——软件建模与分析》阅读笔记3
  17. 我的汉字输入法编码方案
  18. Superset系列9- 制作地图
  19. 将被雪藏的AI算法,抛开快手和火山,YouTube的儿童APP值得学习吗?
  20. Selenium登录百度贴吧跳过图片验证的两种操作

热门文章

  1. FPGA从入门到精通(番外篇1)-AXI VIP的使用
  2. python入门电子版-Python3零基础教材电子书合集
  3. 团队失败常见的10个原因,原因大多在领导!
  4. 2020-03-29
  5. 购车分期系统-智能风控体系,有效控制贷款风险
  6. 用汇编语言写一个程序,它先接收一个字符串,然后显示其中数字符的个数、英文字母的个数和字符串的长度
  7. EasyExcel自适应行高
  8. LeetCode 168 Excel Sheet Column Title
  9. 第127届广交会闭幕,建立线上贸易新机制
  10. STM32外部中断与(NVIC)中断优先级管理