]> O.S.I.I.S - jp/crow.git/commitdiff
remove oldDataSource second way bindings
authorjpbruyere <jp.bruyere@hotmail.com>
Fri, 23 Dec 2016 23:36:27 +0000 (00:36 +0100)
committerjpbruyere <jp.bruyere@hotmail.com>
Fri, 23 Dec 2016 23:36:27 +0000 (00:36 +0100)
src/CompilerServices/CompilerServices.cs
src/Instantiator.cs

index dc95aca86dca64e1a1a0b78989d41d45426e8c45..b7d24184cd8a466d76e9ecd8994f3a9166013b53 100644 (file)
@@ -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<Binding> 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
                /// <summary>
                /// Removes delegate from event handler by name
                /// </summary>
-               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);
-                                       }
                                }
                        }
                }
+               /// <summary>
+               /// Removes delegate from event handler by searching for the object they are bond to
+               /// </summary>
+               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;
 
index 5c50db1827fd09f76ca7740f804b13a2d600b584..cdd229afcc53d46a96724f10e8aa6ba587981d2f 100644 (file)
@@ -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);
                }