zoukankan      html  css  js  c++  java
  • Caliburn笔记Action的创建(wpf框架)

        若一个对象被设置成为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完成.

    image

    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;
    }
  • 相关阅读:
    Retrofit源码分析
    Android异步消息机制
    崩溃bug日志总结3
    单例模式
    总结(第一段)
    mysql日期类型比较
    mysql记录(一)
    JSONObject/JSONArray的区别
    java 正则表达式(Pattern ,Matcher)的使用
    javaweb开发中的权限管理的方法
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/1631936.html
Copyright © 2011-2022 走看看