private static void Complete(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            if (m_ObserveType.ContainsKey(type))
            {
                //已经存在了
                return;
            }

            //取得所有Setter和Attribute,接下来组装HookEntity
            HookEntity hookEntity = new HookEntity(type);

            Dictionary <MethodBase, List <object> > setMethodMapAttributes = GetSetterWithAttributesFromType(type, AttributeFilter);

            foreach (var kvp in setMethodMapAttributes)
            {
                hookEntity.SavePropertyChain(kvp.Key, kvp.Value);
            }
            m_ObserveType.Add(type, hookEntity);

            //组装完毕,进行Patch

            HookHelper.Patch(m_ObserveType[type], m_HookProc);
        }
Exemplo n.º 2
0
        public static void OnCanExecuteChanged(HookEntity hookEntity, MethodBase methodBase)
        {
            if (methodBase == null || hookEntity == null)
            {
                return;
            }

            if (!hookEntity.m_MethodMapCommandProperty.ContainsKey(methodBase))
            {
                return;
            }

            foreach (ICommandInfo commandInfo in hookEntity.m_MethodMapCommandProperty[methodBase])
            {
                if (!commandInfo.FoundField)
                {
                    //需要寻找
                    commandInfo.FieldInfo  = FindEvent(commandInfo.PropertyInfo.PropertyType, nameof(ICommand.CanExecuteChanged));
                    commandInfo.FoundField = true;
                }

                if (commandInfo.FieldInfo == null)
                {
                    continue;
                }

                object commandInstance = commandInfo.PropertyInfo.GetValue(null, null);
                if (commandInstance == null)
                {
                    //为null的情况可能是该viewmodel正在创建中(构造函数对某项赋值),所以为null
                    continue;
                }
                InvokeEvent(commandInfo.FieldInfo, commandInstance, new object[] { commandInstance, EventArgs.Empty });
            }
        }
Exemplo n.º 3
0
        public static void Patch(HookEntity hookEntity, MethodInfo hookProc)
        {
            if (hookEntity == null)
            {
                throw new ArgumentNullException(nameof(hookEntity));
            }
            if (hookProc == null)
            {
                throw new ArgumentNullException(nameof(hookProc));
            }

            foreach (MethodBase method in hookEntity.WillBeHookSetter)
            {
                m_HookHelper.Patch(method, null, new HarmonyMethod(hookProc), null);
            }
        }
        /// <summary>
        /// 执行完Setter后的方法
        /// </summary>
        /// <param name="__instance"></param>
        /// <param name="__originalMethod"></param>
        private static void PropertyChanged(object __instance, MethodBase __originalMethod)
        {
            if (__originalMethod == null)
            {
                return;
            }

            if (__originalMethod.IsStatic)
            {
                //如果这个方法是静态的,那么__instance为null,那么他通知的成员也一定是静态的

                Type type = __originalMethod.DeclaringType; //取到包含该Setter的类
                if (!m_ObserveType.ContainsKey(type))
                {
                    return;
                }

                //因为INotifyPropertyChanged依赖instance,所以这里只能通知CanExecuteChanged
                HookEntity.OnCanExecuteChanged(m_ObserveType[type], __originalMethod);
            }
            else
            {
                if (__instance == null)
                {
                    return;
                }

                Type type = __instance.GetType();
                if (!m_ObserveType.ContainsKey(type))
                {
                    return;
                }

                HookEntity hookEntity = m_ObserveType[type];

                hookEntity.OnPropertyChanged(__instance, __originalMethod);
                hookEntity.OnCanExecuteChanged(__instance, __originalMethod);
            }
        }