Caliburn笔记-Action的创建(wpf框架)
2009-12-25 11:24 Clingingboy 阅读(1264) 评论(0) 编辑 收藏 举报
若一个对象被设置成为DataContext,该对象的方法称之为Action,caliburn通过附加属性来绑定这些Action,首先则需要获取绑定对象的方法.如下示例对象,则有4个方法.
[Rescue("GeneralRescue")] public class Calculator { //Note: This rescue catches exceptions thrown by this method. //[Rescue("ActionSpecificRescue")] //Note: Preview indicates something that will happen before execution of the action. //Note: If AffectsTriggers = false, then this filter will not effect the state of the UI in real time. // [Preview("CanDivide")] //Note: The return value is bound to the UI if present. public int Divide(int left, int right) { return left / right; } //Note: See Preview filter. public bool CanDivide(int left, int right) { return right != 0; } //Note: See class level rescue filter. public void GeneralRescue(Exception ex) { MessageBox.Show(ex.Message); } //Note: See rescue filter on Divide method. public void ActionSpecificRescue(Exception ex) { MessageBox.Show("Divide Action: " + ex.Message); } }
Action只包含公开方法,并不包含属性与事件等,所以需要对象成员进行过滤.如下逻辑
protected virtual IEnumerable<IGrouping<string, MethodInfo>> SelectMethods(Type targetType) { return from method in targetType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static) where method.DeclaringType != typeof(object) && !method.ContainsGenericParameters && !method.Name.StartsWith("get_") && !method.Name.StartsWith("set_") && !method.Name.StartsWith("remove_") && !method.Name.StartsWith("add_") && method.GetParameters().All(x => !x.IsOut) group method by method.Name into groups select groups; }
方法与Action的转换
完成方法过滤后,为了添加功能,还要对方法进行转换.
首先根据方法,创建一个IMethod.然后创建Action.
当然Action还有其他功能,这里分为同步与异步.
protected virtual IAction CreateAction(IActionHost host, MethodInfo methodInfo) { var method = _methodFactory.CreateFrom(methodInfo); var asyncAtt = method.GetMetadata<AsyncActionAttribute>(); var filters = host.GetFilterManager(method); TryAddCanExecute(filters, method); if(asyncAtt == null) return new SynchronousAction(method, _messageBinder, filters); return new AsynchronousAction(method, _messageBinder, filters, asyncAtt.BlockInteraction); }
创建好以后再将其保存,创建过程由实现IActionFactory接口的ActionFactory完成.
public IEnumerable<IAction> CreateFor(IActionHost host) { var actions = new List<IAction>(); var methodGroups = SelectMethods(host.TargetType); foreach(var methodGroup in methodGroups) { var methodList = methodGroup.ToList(); if(methodList.Count == 1) actions.Add(CreateAction(host, methodList[0])); else { var overloadedAction = new OverloadedAction(methodGroup.Key); foreach(var methodInfo in methodList) { overloadedAction.AddOverload(CreateAction(host, methodInfo)); } actions.Add(overloadedAction); } } return actions; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现