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; }