理解WPF Stylet中Command=“{s:Action 方法名}“的设计与实现 - 实践

news/2025/10/11 20:51:27/文章来源:https://www.cnblogs.com/lxjshuju/p/19135964

前言

Stylet是我最近很喜欢使用的一个WPF框架,它的很多设计都体现了约定优于配置的思想。因此你会发现使用它非常方便,几乎不需要任何配置,开箱即用,只需知道它的一些约定即可。

查看Samples中Hello这个例子,只要在xaml中这样写:

Say Hello

然后你点击这个按钮,就会触发对应ViewModel中的SayHello方法,使用起来非常简单方便。这背后Stylet框架做了什么呢?让我们揭开它的神秘面纱吧!!

ActionExtension

先来看看ActionExtension,它位于Stylet.Xaml命名空间:

s:Action的第一阶段是XAML解析,这个阶段的核心任务是将XAML标记中的{s:Action SayHello}语法翻译成CommandAction实例。这个过程由ActionExtension标记扩展类完成,它是整个命令绑定系统的入口点。

当XAML解析器遇到{s:Action SayHello}时,会调用ActionExtension.ProvideValue方法:

HandleDependencyObject方法根据目标属性的类型进行分支处理:

对于命令绑定场景,CreateCommandAction方法创建CommandAction实例:

rootObject就是具有s:Action的页面:

View.ActionTarget

现在我们已经找到了View,但是想要触发的方法是在ViewModel上的,那么就要想办法找到对应的ViewModelStylet中是通过View.ActionTarget这个附加属性实现的。通过View.ActionTarget附加属性将ViewModel注入到可视化树中,使得后续阶段能够找到正确的命令执行目标。

先来看看View.ActionTarget的定义,位置在命名空间Stylet.Xaml下的View类中:

默认值:InitialActionTarget(一个特殊的标记对象)

继承性:FrameworkPropertyMetadataOptions.Inherits确保属性值可以沿着可视化树向下传递

View.Model属性被设置时,会触发PropertyChangedCallback,通过ViewManager建立视图和ViewModel的关联。

在将ViewViewModel关联起来的时候,设置了当前ViewActionTarget为对应的ViewModel

CommandAction

CreateCommandAction方法中会返回一个CommandAction

这里是在把当前这个Subject对象里的ActionTargetProperty的值‘拴’到 某个尚未显式的目标属性上,而且只让它从源(Subject)流向目标,不会反向同步。

这里的SubjectButton对象,为什么也能找到ActionTargetProperty这个属性呢?

由于ActionTargetProperty设置了FrameworkPropertyMetadataOptions.Inherits标志,这个属性会自动沿着可视化树向下传播:

Window (View.ActionTargetProperty)
├── UserControl (继承Window的View.ActionTargetProperty)
│ ├── Button (继承UserControl的View.ActionTargetProperty)
│ └── TextBox (继承UserControl的View.ActionTargetProperty)
└── Grid (继承Window的View.ActionTargetProperty)

但是现在还没完成绑定,只是绑定的一端,还需要设置将这个属性绑定到哪里。

BindingOperations.SetBinding(this, targetProperty, multiBinding);ActionBasetargetProperty依赖属性绑定到View.ActionTargetProperty

你会发现现在并没有绑定到ViewModel,只是View.ActionTargetProperty的默认值:

由于targetProperty依赖属性从nullView.InitialActionTarget也会触发UpdateActionTarget,不过这一次不做任何处理,直接返回:

当设置View.ActionTargetProperty的值为对应的ViewModel时:

就又会触发UpdateActionTarget方法,这一次拿到了对应的ViewModel

拿到ViewModel上的方法:

拿到是否可以执行对应命令的属性:

现在重点来关注一下这里:

Expressions.ConstantExpression targetExpression = Expressions.Expression.Constant(newTarget);
Expressions.MemberExpression propertyAccess = Expressions.Expression.Property(targetExpression, guardPropertyInfo);
this.guardPropertyGetter = Expressions.Expression.Lambda<Func<
bool>
>(propertyAccess).Compile();

这段代码在运行时动态编译一段表达式树,生成一个无参、返回 bool的委托(Func<bool>),用来快速读取某个对象的布尔型属性值。

第一行相当于就是使用这个newTarget对象,第二行就是访问这个newTarget对象的CanSayHello属性,相当于newTarget.CanSayHello

Expression.Lambda<Func<bool>>将表达式树包装成一个无参Lambda表达式(形如 () => newTarget.CanSayHello)。

.Compile()把表达式树编译成可执行IL ,生成一个静态缓存的委托Func<bool>

然后调用this.UpdateCanExecute();触发CanExecuteChanged事件,就会执行CanExecute方法,在这个方法中就使用到了刚刚生成的获取newTarget.CanSayHello属性的委托:

现在是false,命令无法执行:

当我输入小明的时候就修改了这个属性值,就会触发CanExecuteChanged事件:

就又会调用刚刚生成的那个获取newTarget.CanSayHello属性的委托:

这一次返回true,命令可以执行。

当我点击按钮的时候,如果命令可以执行,就会执行Execute方法

这样就会执行ViewModel中对应的方法。

以上就是个人对于WPF Stylet中Command="{s:Action SayHello}"的设计与实现的理解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/935106.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025环氧地坪漆厂家推荐:常州新禾,品质保证施工无忧!

2025环氧地坪漆厂家推荐:常州新禾,品质保证施工无忧!随着工业化和城市化进程的加快,环氧地坪漆的应用越来越广泛。然而,这一领域的技术挑战也日益凸显,如何选择一家可靠的环氧地坪漆厂家成为众多企业和工程项目的…

2025上海经侦律师TOP5榜单:专业法律服务与高效解决方案

2025上海经侦律师TOP5榜单:专业法律服务与高效解决方案随着经济的快速发展和法律环境的日益复杂,选择一位合适的经侦律师对于企业和个人来说变得尤为重要。本文将为您推荐上海地区在经侦领域表现突出的五家律师事务所…

laya自定义滚动条

laya自定义滚动条滚动条不是纯色, 不好缩放, 可以使用蒙版自己移动图片 testBar是滚动条, 使用jdt.png, jdt$bar是个透明图片. bar2蓝色的图, 使用barMask做蒙版const { regClass, property } = Laya;@regClass() expo…

SigOJ提交语言帮助文档 - lkjy

View PostSigOJ提交语言帮助文档可供无法访问AcWing版本的用户访问。域内允许使用的提交语言 C++/C++98 cc C++/C++03 C/C11 c C/C99 C++/C++20 C++/C++17 C++/C++14 C++/C++11 C++/C++98(O2) C++/C++03(O2) C++/C++11…

2025家居ERP推荐:赛思软件助力企业高效管理!

2025家居ERP推荐:赛思软件助力企业高效管理!随着家居行业的快速发展,企业对信息化管理的需求日益增长。在众多的家居ERP解决方案中,如何选择一款适合自身需求的产品成为了一个重要课题。本文将深入探讨当前家居ERP…

2025彩钢瓦保养优质厂家推荐,江苏承优建筑工程专业服务!

2025彩钢瓦保养优质厂家推荐,江苏承优建筑工程专业服务!随着建筑行业的快速发展,彩钢瓦作为一种轻质、耐腐蚀的建筑材料,在各类建筑中得到了广泛应用。然而,彩钢瓦在使用过程中会面临诸多问题,如锈蚀、老化等,这…

优维科技一面

1、介绍一下你实习期间的工作,主要负责哪一块的工作 2、介绍一下你的ES同步吗 3、你是怎么发现你的es的数据不一致的 4、你的数据库同步es的时间需要多少 4、那如果是同步失败了,你们是怎么知道的,通过什么工具或者…

2025磁力泵加工厂推荐中正化工,专业定制高效耐用产品!

2025磁力泵加工厂推荐中正化工,专业定制高效耐用产品!随着工业技术的不断进步,磁力泵在化工、制药、环保等领域的应用越来越广泛。然而,当前磁力泵领域仍然面临诸多技术挑战,这些问题不仅影响了设备的性能和寿命,…

完整教程:《机器学习与深度学习》入门

完整教程:《机器学习与深度学习》入门2025-10-11 20:29 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !…

2025双氧水供应厂家推荐:苏州市岚昱化工品质卓越选择!

2025双氧水供应厂家推荐:苏州市岚昱化工品质卓越选择!当前双氧水领域技术挑战随着环保意识的提升和工业生产的不断升级,双氧水作为一种重要的氧化剂,在多个行业中发挥着重要作用。然而,双氧水生产与应用过程中也面…

深入解析:FreeRTOS内存分配与STM32内存布局详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025婚纱照拍摄推荐,南通造物摄影有限公司专业团队打造梦幻

2025婚纱照拍摄推荐,专业团队打造梦幻随着科技的不断进步和消费者需求的日益多样化,婚纱照拍摄领域面临着诸多技术挑战。本文将深入探讨当前婚纱照领域的技术问题,并介绍南通造物摄影有限公司如何通过其核心实力和技…

2025上海保洁公司最新推荐榜:高效清洁与贴心服务的优质选择

2025上海保洁公司最新推荐榜:高效清洁与贴心服务的优质选择随着城市化进程的加快,人们对生活环境和工作环境的要求越来越高。保洁服务作为维护环境卫生的重要环节,其重要性不言而喻。为了帮助筛选保洁公司品牌,特此…

「解题报告」蓝桥杯2013省AB 错误票据

P8598 [蓝桥杯 2013 省 AB] 错误票据 题目背景 某涉密单位下发了某种票据,并要在年终全部收回。 题目描述 每张票据有唯一的 ID 号,全年所有票据的 ID 号是连续的,但 ID 的开始数码是随机选定的。因为工作人员疏忽,…

2025精密弹簧优质厂家推荐:蓝侨盈科技,精准弹性解决方案!

2025精密弹簧优质厂家推荐:蓝侨盈科技,精准弹性解决方案!当前精密弹簧领域技术挑战随着工业制造技术的不断进步,精密弹簧在各个领域的应用越来越广泛。然而,精密弹簧的生产过程中仍然面临着诸多技术挑战。首先,材…

时时想起 寸步难行 叩问自己 无人回应 若我离去 若我死去 枯萎于这幽暗的井底 长眠不醒

test16 一个困难的问题difficult 首先区间排序是假的,因为可以冒泡排序,这样子可能好考虑一点。 不难发现可以倒序考虑,要贡献的选择后缀中最小未选择的即可,构造的话可以直接从后往前考虑每次最小值的位置一定在上…

有限空间作业安全无死角!AI 视觉守护人员与操作合规

有限空间作业(如地下管沟、隧道、下水道)因环境特殊,安全管理难度极大:作业环境昏暗、多水雾水气,手机拍摄画面模糊,人工巡检难发现未穿防护服、安全帽未系带等隐患;仅靠人工盯守监控,易漏检入口处安全标识缺失…

2025抖音推广服务商最新推荐榜:精准引流与高效转化的营销利

2025抖音推广服务商最新推荐榜:精准引流与高效转化的营销利器随着短视频平台的迅速崛起,抖音已成为众多品牌和企业进行营销推广的重要渠道。为了帮助企业在激烈的市场竞争中脱颖而出,选择一家优质的抖音推广服务商至…