if (dataSource == value)
return;
- DataSourceChangeEventArgs dse = new DataSourceChangeEventArgs (dataSource, null);
-
+ DataSourceChangeEventArgs dse = new DataSourceChangeEventArgs (dataSource, value);
dataSource = value;
- dse.NewDataSource = DataSource;
-
OnDataSourceChanged (this, dse);
NotifyValueChanged ("DataSource", DataSource);
ParentChanged.Raise (sender, e);
}
- #region Binding
-// public void BindMember(string _member, string _expression){
-// Bindings.Add(new Binding (this, _member, _expression));
-// }
-// public virtual void ResolveBindings()
-// {
-// if (Bindings.Count == 0)
-// return;
-// #if DEBUG_BINDING
-// Debug.WriteLine ("Resolve Bindings => " + this.ToString ());
-// #endif
-//
-// CompilerServices.ResolveBindings (Bindings);
-// }
-
- /// <summary>
- /// Remove dynamic delegates by ids from dataSource
- /// and delete ref of this in Shared interface refs
- /// </summary>
-// public virtual void ClearBinding(){
-// //dont clear binding if dataSource is not null,
-// foreach (Binding b in Bindings) {
-// try {
-// if (!b.Resolved)
-// continue;
-// //cancel compiled events
-// if (b.Target == null){
-// continue;
-// #if DEBUG_BINDING
-// Debug.WriteLine("Clear binding canceled for => " + b.ToString());
-// #endif
-// }
-// if (b.Target.Instance != DataSource){
-// #if DEBUG_BINDING
-// Debug.WriteLine("Clear binding canceled for => " + b.ToString());
-// #endif
-// continue;
-// }
-// #if DEBUG_BINDING
-// Debug.WriteLine("ClearBinding => " + b.ToString());
-// #endif
-// if (string.IsNullOrEmpty (b.DynMethodId)) {
-// b.Resolved = false;
-// if (b.Source.Member.MemberType == MemberTypes.Event)
-// removeEventHandler (b);
-// //TODO:check if full reset is necessary
-// continue;
-// }
-// MemberReference mr = null;
-// if (b.Target == null)
-// mr = b.Source;
-// else
-// mr = b.Target;
-// Type dataSourceType = mr.Instance.GetType();
-// EventInfo evtInfo = dataSourceType.GetEvent ("ValueChanged");
-// FieldInfo evtFi = CompilerServices.GetEventHandlerField (dataSourceType, "ValueChanged");
-// MulticastDelegate multicastDelegate = evtFi.GetValue (mr.Instance) as MulticastDelegate;
-// if (multicastDelegate != null) {
-// foreach (Delegate d in multicastDelegate.GetInvocationList()) {
-// if (d.Method.Name == b.DynMethodId)
-// evtInfo.RemoveEventHandler (mr.Instance, d);
-// }
-// }
-// b.Reset ();
-// } catch (Exception ex) {
-// Debug.WriteLine("\t Error: " + ex.ToString());
-// }
-// }
-// }
-// void removeEventHandler(Binding b){
-// FieldInfo fiEvt = CompilerServices.GetEventHandlerField (b.Source.Instance.GetType(), b.Source.Member.Name);
-// MulticastDelegate multiDel = fiEvt.GetValue (b.Source.Instance) as MulticastDelegate;
-// if (multiDel != null) {
-// foreach (Delegate d in multiDel.GetInvocationList()) {
-// if (d.Method.Name == b.Target.Member.Name)
-// b.Source.Event.RemoveEventHandler (b.Source.Instance, d);
-// }
-// }
-// }
- #endregion
-
#region IXmlSerializable
public virtual System.Xml.Schema.XmlSchema GetSchema ()
{
}
#endregion
+ void readPropertyBinding (Context ctx, string sourceMember, string expression)
+ {
+ NodeAddress sourceNA = ctx.CurrentNodeAddress;
+ BindingDefinition bindingDef = splitBindingExp (sourceNA, sourceMember, expression);
+
+ if (bindingDef.IsDataSourceBinding)//bind on data source
+ emitDataSourceBindings (ctx, sourceMember, bindingDef.TargetMember);
+ else
+ ctx.StorePropertyBinding (bindingDef);
+ }
+
string[] splitOnSemiColumnOutsideAccolades (string expression){
List<String> exps = new List<string>();
int accCount = 0;
exps.Add(expression);
return exps.ToArray ();
}
- void readPropertyBinding (Context ctx, string sourceMember, string expression)
- {
- NodeAddress sourceNA = ctx.CurrentNodeAddress;
- BindingDefinition bindingDef = splitBindingExp (sourceNA, sourceMember, expression);
-
- if (bindingDef.IsDataSourceBinding)//bind on data source
- emitDataSourceBindings (ctx, sourceMember, bindingDef.TargetMember);
- else
- ctx.StorePropertyBinding (bindingDef);
- }
/// <summary>
/// Gets the node adress from binding expression splitted with '/' starting at a given node
/// </summary>
}
#endregion
+ #region Event Bindings
/// <summary>
/// Compile events expression in IML attributes, and store the result in the instanciator
/// Those handlers will be bound when instatiing
cachedDelegates.Add (dm.CreateDelegate (sourceEvent.EventHandlerType));
ctx.emitCachedDelegateHandlerAddition(dmIdx, sourceEvent);
}
+ /// <summary> Emits handler method bindings </summary>
void emitHandlerBinding (Context ctx, EventInfo sourceEvent, string expression){
NodeAddress currentNode = ctx.CurrentNodeAddress;
BindingDefinition bindingDef = splitBindingExp (currentNode, sourceEvent.Name, expression);
if (bindingDef.IsTemplateBinding | bindingDef.IsDataSourceBinding) {
//we need to bind datasource method to source event
- DynamicMethod dm = new DynamicMethod ("dyn_dschangedForHandler",
+ DynamicMethod dm = new DynamicMethod ("dyn_dschangedForHandler" + NewId,
typeof(void),
CompilerServices.argsBoundDSChange, true);
il.Emit (OpCodes.Nop);
+ emitRemoveOldDataSourceHandler(il, sourceEvent.Name, bindingDef.TargetMember);
+
//fetch method in datasource and test if it exist
il.Emit (OpCodes.Ldarg_2);//load new datasource
il.Emit (OpCodes.Ldfld, CompilerServices.fiDSCNewDS);
il.Emit (OpCodes.Brfalse, cancel);
- il.Emit (OpCodes.Ldarg_1);//load datasource change source where the event handler is as 1st arg of handler.add
+ il.Emit (OpCodes.Ldarg_1);//load datasource change source where the event is as 1st arg of handler.add
if (bindingDef.IsTemplateBinding)//fetch source instance with address
CompilerServices.emitGetInstance (il, bindingDef.SourceNA);
if (bindingDef.IsDataSourceBinding)
ctx.emitCachedDelegateHandlerAddition (delDSIndex, typeof(GraphicObject).GetEvent ("DataSourceChanged"));
- else //template handler binding
+ else //template handler binding, will be added to root parentChanged
templateCachedDelegateIndices.Add (delDSIndex);
} else {//normal in tree handler binding, store until tree is complete (end of parse)
}
}
+ #endregion
+
+ #region Property Bindings
/// <summary>
/// Create and store in the instanciator the ValueChanged delegates
/// those delegates uses grtree functions to set destination value so they don't
#region check if new parent is null
cancel = ilPC.DefineLabel ();
- ilPC.Emit (OpCodes.Ldarg_2);//load new parent
+ ilPC.Emit (OpCodes.Ldarg_2);//load datasource change arg
ilPC.Emit (OpCodes.Ldfld, CompilerServices.fiDSCNewDS);
- ilPC.Emit (OpCodes.Brfalse, cancel);//new parent is null
+ ilPC.Emit (OpCodes.Brfalse, cancel);//new ds is null
#endregion
int i = 0;
PropertyInfo piOrigine = ctx.CurrentNodeType.GetProperty(sourceMember);
//if no dataSource member name is provided, valuechange is not handle and datasource change
//will be used as origine value
+ string delName = "dyn_DSvalueChanged" + NewId;
if (!string.IsNullOrEmpty(dataSourceMember)){
#region create valuechanged method
- dm = new DynamicMethod ("dyn_DSvalueChanged",
+ dm = new DynamicMethod (delName,
typeof (void),
CompilerServices.argsBoundValueChange, true);
//vc dyn meth is stored in a cached list, it will be bound to datasource only
//when datasource of source graphic object changed
dmVC = dsValueChangedDynMeths.Count;
- //Delegate tmp = dm.CreateDelegate(typeof(EventHandler<ValueChangeEventArgs>), this);
dsValueChangedDynMeths.Add (dm);
#endregion
}
il.Emit (OpCodes.Nop);
+ emitRemoveOldDataSourceHandler(il, "ValueChanged", delName);
+
if (!string.IsNullOrEmpty(dataSourceMember)){
- //first test if datasource is null
- il.Emit (OpCodes.Ldarg_2);//load new datasource
+ il.Emit (OpCodes.Ldarg_2);//load datasource change arg
il.Emit (OpCodes.Ldfld, CompilerServices.fiDSCNewDS);
- il.Emit (OpCodes.Brfalse, cancel);
+ il.Emit (OpCodes.Brfalse, cancel);//new ds is null
}
#region fetch initial Value
ctx.emitCachedDelegateHandlerAddition(delDSIndex, typeof(GraphicObject).GetEvent("DataSourceChanged"));
}
+ #endregion
+
+ /// <summary> Emits remove old data source event handler./summary>
+ void emitRemoveOldDataSourceHandler(ILGenerator il, string eventName, string delegateName){
+ System.Reflection.Emit.Label cancel = il.DefineLabel ();
+
+ il.Emit (OpCodes.Ldarg_2);//load old parent
+ il.Emit (OpCodes.Ldfld, typeof (DataSourceChangeEventArgs).GetField ("OldDataSource"));
+ il.Emit (OpCodes.Brfalse, cancel);//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, 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.MarkLabel(cancel);
+ }
+
}
}