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