From: jpbruyere Date: Fri, 23 Dec 2016 23:36:27 +0000 (+0100) Subject: remove oldDataSource second way bindings X-Git-Tag: v0.5.1~63^2~7 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=ec4431d98524dfff79563ca233820d3b29978402;p=jp%2Fcrow.git remove oldDataSource second way bindings --- diff --git a/src/CompilerServices/CompilerServices.cs b/src/CompilerServices/CompilerServices.cs index dc95aca8..b7d24184 100644 --- a/src/CompilerServices/CompilerServices.cs +++ b/src/CompilerServices/CompilerServices.cs @@ -167,7 +167,7 @@ namespace Crow il.Emit (OpCodes.Callvirt, miParse); if (miParse.ReturnType != pi.PropertyType) - il.Emit (OpCodes.Unbox_Any, pi.PropertyType); + il.Emit (OpCodes.Unbox_Any, pi.PropertyType); } else { MethodInfo miParse = pi.PropertyType.GetMethod ("Parse", BindingFlags.Static | BindingFlags.Public, @@ -182,7 +182,7 @@ namespace Crow il.Emit (OpCodes.Unbox_Any, pi.PropertyType); } } - il.Emit (OpCodes.Callvirt, pi.GetSetMethod ()); + il.Emit (OpCodes.Callvirt, pi.GetSetMethod ()); } public static void ResolveBindings (List Bindings) @@ -470,7 +470,7 @@ namespace Crow il.Emit (OpCodes.Ldarg_0); //load sender ref onto the stack string [] lopParts = lop.Split (new char [] { '.' }); - if (lopParts.Length > 1) {//should search also for member of es.Source + if (lopParts.Length > 1) {//should search also for member of es.Source for (int j = 0; j < lopParts.Length - 1; j++) { il.Emit (OpCodes.Ldstr, lopParts [j]); il.Emit (OpCodes.Callvirt, miFindByName); @@ -805,20 +805,34 @@ namespace Crow /// /// Removes delegate from event handler by name /// - public static void RemoveEventHandler(object instance, string eventName, string delegateName){ + public static void RemoveEventHandlerByName(object instance, string eventName, string delegateName){ Type t = instance.GetType (); FieldInfo fiEvt = CompilerServices.GetEventHandlerField (t, eventName); EventInfo eiEvt = t.GetEvent (eventName); MulticastDelegate multiDel = fiEvt.GetValue (instance) as MulticastDelegate; if (multiDel != null) { foreach (Delegate d in multiDel.GetInvocationList()) { - if (d.Method.Name == delegateName) { + if (d.Method.Name == delegateName) eiEvt.RemoveEventHandler (instance, d); - Debug.WriteLine ("event handler removed: " + delegateName + " in " + t.FullName); - } } } } + /// + /// Removes delegate from event handler by searching for the object they are bond to + /// + public static void RemoveEventHandlerByTarget(object instance, string eventName, object target){ + Type t = instance.GetType (); + FieldInfo fiEvt = CompilerServices.GetEventHandlerField (t, eventName); + EventInfo eiEvt = t.GetEvent (eventName); + MulticastDelegate multiDel = fiEvt.GetValue (instance) as MulticastDelegate; + if (multiDel != null) { + foreach (Delegate d in multiDel.GetInvocationList()) { + if (d.Target == target) + eiEvt.RemoveEventHandler (instance, d); + } + } + } + public static Delegate compileDynEventHandler(EventInfo sourceEvent, string expression, NodeAddress currentNode = null){ Type lopType = null; diff --git a/src/Instantiator.cs b/src/Instantiator.cs index 5c50db18..cdd229af 100644 --- a/src/Instantiator.cs +++ b/src/Instantiator.cs @@ -827,6 +827,21 @@ namespace Crow emitRemoveOldDataSourceHandler(il, "ValueChanged", delName); if (!string.IsNullOrEmpty(bindingDef.TargetMember)){ + if (bindingDef.TwoWay){ + System.Reflection.Emit.Label cancelRemove = il.DefineLabel (); + //remove handler if not null + il.Emit (OpCodes.Ldarg_2);//load old parent + il.Emit (OpCodes.Ldfld, typeof (DataSourceChangeEventArgs).GetField ("OldDataSource")); + il.Emit (OpCodes.Brfalse, cancelRemove);//old parent is null + + //remove handler + il.Emit (OpCodes.Ldarg_2);//1st arg load old datasource + il.Emit (OpCodes.Ldfld, typeof (DataSourceChangeEventArgs).GetField ("OldDataSource")); + il.Emit (OpCodes.Ldstr, "ValueChanged");//2nd arg event name + il.Emit (OpCodes.Ldarg_1);//3d arg: instance bound to delegate (the source) + il.Emit (OpCodes.Call, typeof(CompilerServices).GetMethod("RemoveEventHandlerByTarget", BindingFlags.Static | BindingFlags.Public)); + il.MarkLabel(cancelRemove); + } il.Emit (OpCodes.Ldarg_2);//load datasource change arg il.Emit (OpCodes.Ldfld, CompilerServices.fiDSCNewDS); il.Emit (OpCodes.Brfalse, cancel);//new ds is null @@ -949,7 +964,7 @@ namespace Crow il.Emit (OpCodes.Ldfld, typeof (DataSourceChangeEventArgs).GetField ("OldDataSource")); il.Emit (OpCodes.Ldstr, eventName);//2nd arg event name il.Emit (OpCodes.Ldstr, delegateName);//3d arg: delegate name - il.Emit (OpCodes.Call, typeof(CompilerServices).GetMethod("RemoveEventHandler", BindingFlags.Static | BindingFlags.Public)); + il.Emit (OpCodes.Call, typeof(CompilerServices).GetMethod("RemoveEventHandlerByName", BindingFlags.Static | BindingFlags.Public)); il.MarkLabel(cancel); }