嗯。。最近回家去了,2个月没写过代码了,面试只能吹牛,基础都忘了,今天回顾一下,分享一篇通过附加属性去处理窗体弹出的情况。

或许老司机已经想到了,通过设置附加属性值,值变更的回调函数去处理窗体弹出,是的,很简单,想法的问题。

public static readonly DependencyProperty IsModalProperty =
DependencyProperty.RegisterAttached("IsModal", typeof(bool), typeof(WindowHelper), new PropertyMetadata(true)); public static readonly DependencyProperty OpenWindowTypeProperty =
DependencyProperty.RegisterAttached("OpenWindowType", typeof(Type), typeof(WindowHelper), new PropertyMetadata(null, OnOpenWindowTypeChanged)); public static readonly DependencyProperty ParameterProperty =
DependencyProperty.RegisterAttached("Parameter", typeof(object), typeof(WindowHelper), new PropertyMetadata(null));

三个附加属性,是否模态窗口,窗口类型,传递到窗口的参数,事实上其实还是通过反射处理的。

 private static void OnOpenWindowTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

这是OpenWindowType属性的变更回调函数

var type = GetOpenWindowType(d);
if (type == null && type != typeof(Window))
{
return;
} Window window = Activator.CreateInstance(type) as Window; if (window == null)
{
return;
} if (GetParameter(d) != null)
{
window.Tag = GetParameter(d);
} var isModel = GetIsModal(d); window.Closed += (win, closeArgs) =>
{ window = null;
}; if (isModel)
{
window.ShowDialog();
}
else
{
window.Show();
}

是吧,函数实现还是很简单的,看着明白了,那还少一点东西,什么呢? 怎么触发这个变更函数!

在说触发的问题的时候,怎么想想怎么使用它

attached:WindowHelper.IsModal="True"
attached:WindowHelper.OpenWindowType="{x:Type local:Window1}"

是吧,添加引用然后设置属性

这个附加属性我们添加到哪里呢?当然是哪里用加哪里了。 所以可能是点击button弹窗,也可能是menuitem

所以,我们要添加下面这段代码,在属性变更函数之前

dynamic control = null;
switch (d.GetType().Name.ToString())
{
case "Button":
control = d as Button;
break; case "Hyperlink":
control = d as Hyperlink;
break; case "MenuItem":
control = d as MenuItem;
break; default:
return;
}
var type = GetOpenWindowType(d);
if (type == null && type != typeof(Window))
{
return;
} Window window = null;
var clickEventHandler = new RoutedEventHandler((s, arg) =>
{
if (window == null)
{
window = Activator.CreateInstance(type) as Window; if (window == null)
{
return;
}
} if (GetParameter(d) != null)
{
window.Tag = GetParameter(d);
} var isModel = GetIsModal(d); window.Closed += (win, closeArgs) =>
{ window = null;
}; if (isModel)
{
window.ShowDialog();
}
else
{
window.Show();
}
}); control.Click += clickEventHandler;

事实上,这个属性变更只会有一次,就是初始化的时候,所以我们在初始化的时候给按钮注册了事件,每次点击的时候去弹出窗体,做到这一步其实其他的就很好处理了,比如给vm传递参数,是不是用window.DataContext as VM,然后传递就可以了?当然更好的方式是写一个公共的接口,让VM去继承做处理。比如窗口关闭后需要调用某个函数做一些功能,是不是好实现多了,再加一个ICommand类型的附加属性不就可以了。

分享就到这里,有更好的方案的同学可以加页面下方的群,欢迎讨论

WPF实战案例-MVVM模式下用附加属性在Xaml中弹出窗体的更多相关文章

  1. WPF实战案例-MVVM模式下在Xaml中弹出窗体

    相信很多学习和开发wpf项目的同学都了解过mvvm模式,同样,在mvvm模式下会有一个不可忽视的问题,就是怎么在xaml中弹出窗体,而不破坏MVVM本身的结构. 关于弹出窗体的方式还是很多的,本文先讲 ...

  2. WPF中在MVVM模式下,后台绑定ListCollectionView事件触发问题

    问题:WPF中MVVM模式下 ListView绑定ListCollectionView时,CurrentChanged无法触发 解决方案: 初期方案:利用ListView的SelectionChang ...

  3. MVVM模式下WPF动态绑定展示图片

    MVVM模式下WPF动态展示图片,界面选择图标,复制到项目中固定目录下面,保存到数据库的是相对路径,再次读取的时候是根据数据库的相对路径去获取项目中绝对路径的图片展示. 首先在ViewModel中 / ...

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

    原文:wpf mvvm模式下CommandParameter传递多参 CommandParameter一般只允许设置一次,所以如果要传递多参数,就要稍微处理一下.我暂时还没找到更好的方案,下面介绍的这 ...

  5. WPF MVVM模式下ComboBox级联效果 选择第一项

    MVVM模式下做的省市区的级联效果.通过改变ComboBox执行命令改变市,区. 解决主要问题就是默认选中第一项 1.首先要定义一个属性,继承自INotifyPropertyChanged接口.我这里 ...

  6. 如何从40亿整数中找到不存在的一个 webservice Asp.Net Core 轻松学-10分钟使用EFCore连接MSSQL数据库 WPF实战案例-打印 RabbitMQ与.net core(五) topic类型 与 headers类型 的Exchange

    如何从40亿整数中找到不存在的一个 前言 给定一个最多包含40亿个随机排列的32位的顺序整数的顺序文件,找出一个不在文件中的32位整数.(在文件中至少确实一个这样的数-为什么?).在具有足够内存的情况 ...

  7. Silverlight中在MVVM模式下对DatagridRow选择控件封装

    在项目中,凡是涉及到表格的地方用的最多的控件,自然少不了DataGrid的身影,它明了的展示各种数据让人十分喜欢.现在要实现一个功能,使DataGrid具有全选和项选中的功能,如果在传统后台代码中完成 ...

  8. MVVM模式下弹出窗体

    原地址:http://www.cnblogs.com/yk250/p/5773425.html 在mvvm模式下弹出窗体,有使用接口模式传入参数new一个对象的,还有的是继承于一个window,然后在 ...

  9. js架构设计模式——MVVM模式下,ViewModel和View,Model有什么区别

    MVVM模式下,ViewModel和View,Model有什么区别 Model:很简单,就是业务逻辑相关的数据对象,通常从数据库映射而来,我们可以说是与数据库对应的model. View:也很简单,就 ...

随机推荐

  1. 如何解决docker 官方镜像拉取慢的问题

    转自: http://skycity.today/?thread-307.htm 国内从 docker 官方 Registry 拉取 image 慢的解决,步骤如下: 1.注册一个阿里云账号. 2.阿 ...

  2. 【ARM-Linux开发】Linux内存管理:ARM Memory Layout以及mmu配置

    原文:Linux内存管理:ARM Memory Layout以及mmu配置 在内核进行page初始化以及mmu配置之前,首先需要知道整个memory map. 1. ARM Memory Layout ...

  3. 【编程开发】非对称加密过程详解(基于RSA非对称加密算法实现)

    1.非对称加密过程:         假如现实世界中存在A和B进行通讯,为了实现在非安全的通讯通道上实现信息的保密性.完整性.可用性(即信息安全的三个性质),A和B约定使用非对称加密通道进行通讯,具体 ...

  4. [LuoguP2159][SHOI2009]舞会_动态规划_高精度_排列组合

    舞会 题目链接:https://www.luogu.org/problem/P2159 数据范围:略. 题解: 不会.... 看了题解觉得自己好傻逼啊

  5. [转帖]四个修改Docker默认存储位置的方法

    四个修改Docker默认存储位置的方法 https://blog.51cto.com/forangela/1949947 易改乾坤关注0人评论27435人阅读2017-07-22 09:18:48   ...

  6. python查询neo4j的数据以字典的方式返回数据

    在使用python操作neo4j的时候,如果查询的数据比较多,结构比较复杂的时候,返回的数据量会比较大,而且信息比较多,并且不唯一.所以写了该方法,用于查询比较复杂的数据. def query_gra ...

  7. 【AtCoder】AGC007

    AGC007 A - Shik and Stone 如果i + j走过的格子只有一个,那么就是可以走到 #include <bits/stdc++.h> #define fi first ...

  8. Kubernetes---Pod状态示例

    ⒈Pod 中只有一个容器并且正在运行,容器成功退出 ·记录事件完成  ·如果restartPolicy为:  Always:重启容器:Pod phase仍为Running  OnFailure:Pod ...

  9. jQuery获取当前checkbox的值

    背景: 目前想实现登录的“记住我”功能,需要获取当前checkbox是否被点击,百度了一通,全是多个复选框选中了哪一个的解答, 迫于无奈,自己在W3school上面查询了checkbox的所有属性,并 ...

  10. spark异常篇-Removing executor 5 with no recent heartbeats: 120504 ms exceeds timeout 120000 ms 可能的解决方案

    问题描述与分析 题目中的问题大致可以描述为: 由于某个 Executor 没有按时向 Driver 发送心跳,而被 Driver 判断该 Executor 已挂掉,此时 Driver 要把 该 Exe ...