嗯。。最近回家去了,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. [dart学习]第六篇:流程控制语句

    经过前面的基础知识了解学习,我们今天可以进入语句模块啦. dart主要有以下流程控制语句: if-else for循环 while和do-while循环 break和continue switch-c ...

  2. 关于运维之故障复盘篇-Case Study

    关于故障的事后复盘,英文名 Case Study是非常有必要做的,当然是根据故障的级别,不可能做到每个故障都Case Study,除非人员和时间充足: 文档能力也是能力的一种,一般工程师的文档能力比较 ...

  3. Spring Aop(十二)——编程式的创建Aop代理之AspectjProxyFactory

    转发地址:https://www.iteye.com/blog/elim-2397922 编程式的创建Aop代理之AspectjProxyFactory 之前已经介绍了一款编程式的创建Aop代理的工厂 ...

  4. iOS-iOS 支付 [支付宝、银联、微信](转)

    支付宝iOSsdk官方下载sdk地址:https://b.alipay.com/order/productDetail.htm?productId=2013080604609654&tabId ...

  5. EPP状态码

    服务器状态代码由您的域的注册表设置 EPP状态码 RDAP状态映射 这是什么意思? 你应该做点什么吗? addPeriod 加期 该宽限期是在域名初始注册后提供的.如果注册服务商在此期间删除了域名,则 ...

  6. mysql学习笔记11_18(更新、插入和删除)

    1.初始表 mysql> select * from department; 2.修改销售部的地点为杭州 mysql> update department set address = '杭 ...

  7. whereis which type find

    1. whereis  name whereis命令只能用于搜索程序名,而且只搜索二进制文件(参数-b).man说明文件(参数-m)和源代码文件(参数-s).如果省略参数,则返回所有信息. 2. wh ...

  8. idea开发shell脚本并运行

    参考:https://blog.csdn.net/u012443641/article/details/81295999 IEDA中的bashsupport插件支持在IDEA中编写shell脚本文件, ...

  9. poj1947(树上分组背包)

    题目链接:https://vjudge.net/problem/POJ-1947 题意:给定一棵树,求得到一个结点数为p最少删多少条边. 思路: 明显的树形dp,分组背包.用dp[u][j]表示在结点 ...

  10. Oracle存储过程——日常记录

    代码规范 Oracle存储过程,关键字大写,变量小写并以v_开头,规范代码,提高可读性 赋值与判断符号 Oracle存储过程,变量赋值使用 := 符号,条件判断直接用 = 符号. 变量声明需在 beg ...