aboutsummaryrefslogtreecommitdiffstatsci
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CompilerServices/CompilerServices.cs50
-rw-r--r--src/GraphicObjects/GraphicObject.cs39
-rw-r--r--src/GraphicObjects/Group.cs4
-rw-r--r--src/GraphicObjects/PrivateContainer.cs4
-rw-r--r--src/GraphicObjects/TabItem.cs6
-rw-r--r--src/GraphicObjects/TemplatedGroup.cs3
-rw-r--r--src/IML/BindingDefinition.cs15
-rw-r--r--src/Instantiator.cs46
-rw-r--r--src/Interface.cs1
9 files changed, 123 insertions, 45 deletions
diff --git a/src/CompilerServices/CompilerServices.cs b/src/CompilerServices/CompilerServices.cs
index b7d24184..2a472f3c 100644
--- a/src/CompilerServices/CompilerServices.cs
+++ b/src/CompilerServices/CompilerServices.cs
@@ -643,6 +643,38 @@ namespace Crow
public static Type getEventHandlerType(object instance, string eventName){
return instance.GetType ().GetEvent (eventName).EventHandlerType;
}
+ public static void setValueWithReflexion(object dest, object value, string destMember){
+ Type destType = null;
+ Type origType = null;
+ object convertedVal = null;
+
+ MemberInfo miDest = getMemberInfoWithReflexion (dest, destMember);
+
+ if (miDest == null) {
+ Debug.WriteLine ("Reverse template binding error: " + destMember + " not found in " + dest);
+ return;
+ }
+
+ if (miDest.MemberType == MemberTypes.Property)
+ destType =(miDest as PropertyInfo).PropertyType;
+ else if (miDest.MemberType == MemberTypes.Field)
+ destType =(miDest as FieldInfo).FieldType;
+
+ if (value != null) {
+ origType = value.GetType ();
+ if (destType.IsAssignableFrom (origType))
+ convertedVal = Convert.ChangeType (value, destType);
+ else if (origType.IsPrimitive & destType.IsPrimitive)
+ convertedVal = GetConvertMethod (destType).Invoke (null, new Object[] { value });
+ else
+ convertedVal = getImplicitOp (origType, destType).Invoke (value, null);
+ }
+
+ if (miDest.MemberType == MemberTypes.Property)
+ (miDest as PropertyInfo).SetValue (dest, convertedVal);
+ else if (miDest.MemberType == MemberTypes.Field)
+ (miDest as FieldInfo).SetValue (dest, convertedVal);
+ }
public static object getValueWithReflexion(object instance, MemberInfo mi){
object tmp = null;
Type dstType = null;
@@ -674,7 +706,7 @@ namespace Crow
break;
}
for (int i = 0; i < orig.Count - ptr; i++)
- il.Emit (OpCodes.Callvirt, typeof(ILayoutable).GetProperty ("Parent").GetGetMethod ());
+ il.Emit (OpCodes.Callvirt, typeof(ILayoutable).GetProperty ("LogicalParent").GetGetMethod ());
while (ptr < dest.Count) {
emitGetChild (il, dest [ptr-1].CrowType, dest [ptr].Index);
ptr++;
@@ -812,8 +844,12 @@ namespace Crow
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);
+ #if DEBUG_BINDING
+ Debug.WriteLine ("\t{0} handler removed in {1} for: {2}", d.Method.Name,instance, eventName);
+ #endif
+ }
}
}
}
@@ -827,13 +863,21 @@ namespace Crow
MulticastDelegate multiDel = fiEvt.GetValue (instance) as MulticastDelegate;
if (multiDel != null) {
foreach (Delegate d in multiDel.GetInvocationList()) {
- if (d.Target == target)
+ if (d.Target == target) {
eiEvt.RemoveEventHandler (instance, d);
+ #if DEBUG_BINDING
+ Debug.WriteLine ("\t{0} handler removed in {1} for: {2}", d.Method.Name,instance, eventName);
+ #endif
+ }
}
}
}
public static Delegate compileDynEventHandler(EventInfo sourceEvent, string expression, NodeAddress currentNode = null){
+ #if DEBUG_BINDING
+ Debug.WriteLine ("\tCompile Event {0}: {1}", sourceEvent.Name, expression);
+ #endif
+
Type lopType = null;
if (currentNode == null)
diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs
index a2f9be7c..1be9d4cf 100644
--- a/src/GraphicObjects/GraphicObject.cs
+++ b/src/GraphicObjects/GraphicObject.cs
@@ -140,9 +140,12 @@ namespace Crow
return;
if (logicalParent != null)
(logicalParent as GraphicObject).DataSourceChanged -= onLogicalParentDataSourceChanged;
+ DataSourceChangeEventArgs dsce = new DataSourceChangeEventArgs (LogicalParent, null);
logicalParent = value;
+ dsce.NewDataSource = LogicalParent;
if (logicalParent != null)
(logicalParent as GraphicObject).DataSourceChanged += onLogicalParentDataSourceChanged;
+ onLogicalParentChanged (this, dsce);
}
}
[XmlIgnore]public virtual Rectangle ClientRectangle {
@@ -186,6 +189,7 @@ namespace Crow
public event EventHandler<LayoutingEventArgs> LayoutChanged;
public event EventHandler<DataSourceChangeEventArgs> DataSourceChanged;
public event EventHandler<DataSourceChangeEventArgs> ParentChanged;
+ public event EventHandler<DataSourceChangeEventArgs> LogicalParentChanged;
#endregion
#region public properties
@@ -535,37 +539,30 @@ namespace Crow
[XmlAttributeAttribute][DefaultValue(null)]
public virtual object DataSource {
set {
- if (dataSource == value)
+ if (DataSource == value)
return;
- DataSourceChangeEventArgs dse = new DataSourceChangeEventArgs (dataSource, value);
+ DataSourceChangeEventArgs dse = new DataSourceChangeEventArgs (DataSource, null);
dataSource = value;
+ dse.NewDataSource = DataSource;
OnDataSourceChanged (this, dse);
NotifyValueChanged ("DataSource", DataSource);
}
get {
- return dataSource == null ? LogicalParent == null ? null :
- LogicalParent is GraphicObject ?
- (LogicalParent as GraphicObject).DataSource : null : dataSource;
+ return dataSource == null ?
+ LogicalParent == null ? null :
+ LogicalParent is GraphicObject ? (LogicalParent as GraphicObject).DataSource : null :
+ dataSource;
}
}
protected virtual void onLogicalParentDataSourceChanged(object sender, DataSourceChangeEventArgs e){
- ILayoutable tmp = Parent;
- if (tmp == null) {
- Debug.WriteLine ("parent is null for: " + this.ToString ());
- return;
- }
- while (tmp != sender) {
- if (!(tmp as GraphicObject).localDataSourceIsNull) {
- OnDataSourceChanged (sender, e);
- return;
- }
- tmp = tmp.Parent;
- }
+ if (localDataSourceIsNull)
+ OnDataSourceChanged (this, e);
}
internal bool localDataSourceIsNull { get { return dataSource == null; } }
+ internal bool localLogicalParentIsNull { get { return logicalParent == null; } }
public virtual void OnDataSourceChanged(object sender, DataSourceChangeEventArgs e){
DataSourceChanged.Raise (this, e);
@@ -1254,9 +1251,13 @@ namespace Crow
Disabled.Raise (this, e);
}
protected virtual void onParentChanged(object sender, DataSourceChangeEventArgs e) {
- ParentChanged.Raise (sender, e);
+ ParentChanged.Raise (this, e);
+ if (logicalParent == null)
+ LogicalParentChanged.Raise (this, e);
+ }
+ protected virtual void onLogicalParentChanged(object sender, DataSourceChangeEventArgs e) {
+ LogicalParentChanged.Raise (this, e);
}
-
#region IXmlSerializable
public virtual System.Xml.Schema.XmlSchema GetSchema ()
{
diff --git a/src/GraphicObjects/Group.cs b/src/GraphicObjects/Group.cs
index da42b8f5..a285e282 100644
--- a/src/GraphicObjects/Group.cs
+++ b/src/GraphicObjects/Group.cs
@@ -93,9 +93,9 @@ namespace Crow
#region GraphicObject overrides
public override void OnDataSourceChanged (object sender, DataSourceChangeEventArgs e)
{
- base.OnDataSourceChanged (sender, e);
+ base.OnDataSourceChanged (this, e);
foreach (GraphicObject g in children)
- if (g.localDataSourceIsNull)
+ if (g.localDataSourceIsNull & g.localLogicalParentIsNull)
g.OnDataSourceChanged (sender, e);
}
public override GraphicObject FindByName (string nameToFind)
diff --git a/src/GraphicObjects/PrivateContainer.cs b/src/GraphicObjects/PrivateContainer.cs
index 06f0c213..0afefeb9 100644
--- a/src/GraphicObjects/PrivateContainer.cs
+++ b/src/GraphicObjects/PrivateContainer.cs
@@ -80,9 +80,9 @@ namespace Crow
}
public override void OnDataSourceChanged (object sender, DataSourceChangeEventArgs e)
{
- base.OnDataSourceChanged (sender, e);
+ base.OnDataSourceChanged (this, e);
if (child != null)
- if (child.localDataSourceIsNull)
+ if (child.localDataSourceIsNull & child.localLogicalParentIsNull)
child.OnDataSourceChanged (sender, e);
}
public override bool UpdateLayout (LayoutingType layoutType)
diff --git a/src/GraphicObjects/TabItem.cs b/src/GraphicObjects/TabItem.cs
index 078fd04d..cd57b221 100644
--- a/src/GraphicObjects/TabItem.cs
+++ b/src/GraphicObjects/TabItem.cs
@@ -46,7 +46,13 @@ namespace Crow
return _contentContainer == null ? null : _contentContainer.Child;
}
set {
+ if (Content != null) {
+ Content.LogicalParent = null;
+ _contentContainer.SetChild (null);
+ }
_contentContainer.SetChild(value);
+ if (value != null)
+ value.LogicalParent = this;
}
}
protected override void loadTemplate(GraphicObject template = null)
diff --git a/src/GraphicObjects/TemplatedGroup.cs b/src/GraphicObjects/TemplatedGroup.cs
index 7b7f897c..1664f671 100644
--- a/src/GraphicObjects/TemplatedGroup.cs
+++ b/src/GraphicObjects/TemplatedGroup.cs
@@ -42,7 +42,6 @@ namespace Crow
public event EventHandler<SelectionChangeEventArgs> SelectedItemChanged;
#endregion
- Group _list;
IList data;
int _selectedIndex;
Color selBackground, selForeground;
@@ -160,10 +159,12 @@ namespace Crow
public virtual void AddItem(GraphicObject g){
items.AddChild (g);
+ g.LogicalParent = this;
NotifyValueChanged ("HasChildren", true);
}
public virtual void RemoveItem(GraphicObject g)
{
+ g.LogicalParent = null;
items.RemoveChild (g);
if (items.Children.Count == 0)
NotifyValueChanged ("HasChildren", false);
diff --git a/src/IML/BindingDefinition.cs b/src/IML/BindingDefinition.cs
index 59b45167..eadbc9df 100644
--- a/src/IML/BindingDefinition.cs
+++ b/src/IML/BindingDefinition.cs
@@ -64,6 +64,21 @@ namespace Crow.IML
TargetNA = newTargetNA;
TargetName = "";
}
+
+ public override string ToString ()
+ {
+ string tmp = string.Format ("Source:{0}.{1}", SourceNA, SourceMember);
+ if (TwoWay)
+ tmp += " <=> ";
+ else
+ tmp += " <= ";
+
+ if (string.IsNullOrEmpty (TargetName))
+ tmp += string.Format ("Target:{0}.{1}]", TargetNA, TargetMember);
+ else
+ tmp += string.Format ("Target:{0}.{1}.{2}]", TargetNA, TargetName, TargetMember);
+ return tmp;
+ }
}
}
diff --git a/src/Instantiator.cs b/src/Instantiator.cs
index a0f8fe75..4415609b 100644
--- a/src/Instantiator.cs
+++ b/src/Instantiator.cs
@@ -110,7 +110,7 @@ namespace Crow
ctx.nodesStack.Pop ();
foreach (int idx in templateCachedDelegateIndices)
- ctx.emitCachedDelegateHandlerAddition(idx, typeof(GraphicObject).GetEvent("ParentChanged"));
+ ctx.emitCachedDelegateHandlerAddition(idx, typeof(GraphicObject).GetEvent("LogicalParentChanged"));
ctx.ResolveNamedTargets ();
@@ -418,9 +418,6 @@ namespace Crow
/// </summary>
void compileAndStoreDynHandler (Context ctx, EventInfo sourceEvent, string expression)
{
- #if DEBUG_BINDING
- Debug.WriteLine ("\tCompile Event Source ");
- #endif
//store event handler dynamic method in instanciator
int dmIdx = cachedDelegates.Count;
cachedDelegates.Add (CompilerServices.compileDynEventHandler (sourceEvent, expression, ctx.CurrentNodeAddress));
@@ -444,7 +441,7 @@ namespace Crow
il.Emit (OpCodes.Nop);
- emitRemoveOldDataSourceHandler(il, sourceEvent.Name, bindingDef.TargetMember);
+ emitRemoveOldDataSourceHandler (il, sourceEvent.Name, bindingDef.TargetMember, false);
//fetch method in datasource and test if it exist
il.Emit (OpCodes.Ldarg_2);//load new datasource
@@ -477,7 +474,7 @@ namespace Crow
System.Reflection.Emit.Label finish = il.DefineLabel ();
il.Emit (OpCodes.Br, finish);
il.MarkLabel (cancel);
- il.EmitWriteLine (sourcePath + ": Handler method not found: " + bindingDef.TargetMember);
+ il.EmitWriteLine (string.Format ("Handler method '{0}' not found. {1}={2} ", bindingDef.TargetMember, sourceEvent.Name, expression));
il.MarkLabel (finish);
il.Emit (OpCodes.Ret);
@@ -545,17 +542,20 @@ namespace Crow
if (piOrig != null)
origineType = piOrig.PropertyType;
foreach (MemberAddress ma in bindingCase.Value) {
- if (ma.Address.Count == 0)
- continue;//template binding
//first we have to load destination instance onto the stack, it is access
//with graphic tree functions deducted from nodes topology
il.Emit (OpCodes.Ldarg_0);//load source instance of ValueChanged event
NodeAddress destination = ma.Address;
- CompilerServices.emitGetInstance (il, origine, destination);
+ if (destination.Count == 0){//template reverse binding
+ //fetch destination instance (which is the template root)
+ for (int j = 0; j < origine.Count ; j++)
+ il.Emit(OpCodes.Callvirt, typeof(GraphicObject).GetProperty("LogicalParent").GetGetMethod());
+ }else
+ CompilerServices.emitGetInstance (il, origine, destination);
- if (origineType != null){//prop less binding, no init requiered
+ if (origineType != null && destination.Count > 0){//else, prop less binding or reverse template bind, no init requiered
//for initialisation dynmeth, push destination instance loc_0 is root node in ctx
ctx.il.Emit(OpCodes.Ldloc_0);
CompilerServices.emitGetInstance (ctx.il, destination);
@@ -571,13 +571,18 @@ namespace Crow
if (origineType == null)//property less binding, no init
CompilerServices.emitConvert (il, ma.Property.PropertyType);
- else {
+ else if (destination.Count > 0) {
if (origineType.IsValueType)
ctx.il.Emit(OpCodes.Box, origineType);
+
CompilerServices.emitConvert (ctx.il, origineType, ma.Property.PropertyType);
CompilerServices.emitConvert (il, origineType, ma.Property.PropertyType);
ctx.il.Emit (OpCodes.Callvirt, ma.Property.GetSetMethod());//set init value
+ } else {// reverse templateBinding
+ il.Emit (OpCodes.Ldstr, ma.memberName);//arg 3 of setValueWithReflexion
+ il.Emit (OpCodes.Call, typeof(CompilerServices).GetMethod("setValueWithReflexion", BindingFlags.Static | BindingFlags.Public));
+ continue;
}
il.Emit (OpCodes.Callvirt, ma.Property.GetSetMethod());//set value on value changes
}
@@ -603,7 +608,7 @@ namespace Crow
ILGenerator il = dm.GetILGenerator (256);
//create parentchanged dyn meth in parallel to have only one loop over bindings
- DynamicMethod dmPC = new DynamicMethod ("dyn_InitAndParentChanged",
+ DynamicMethod dmPC = new DynamicMethod ("dyn_InitAndLogicalParentChanged",
typeof (void),
CompilerServices.argsBoundDSChange, true);
ILGenerator ilPC = dmPC.GetILGenerator (256);
@@ -663,8 +668,10 @@ namespace Crow
#region destination member affectations
foreach (MemberAddress ma in bindingCase.Value) {
- if (ma.Address.Count == 0)
+ if (ma.Address.Count == 0){
+ Debug.WriteLine("\t\tBUG: reverse template binding in normal template binding");
continue;//template binding
+ }
//first we try to get memberInfo of new parent, if it doesn't exist, it's a propery less binding
ilPC.Emit (OpCodes.Ldarg_2);//load new parent onto the stack for handler addition
ilPC.Emit (OpCodes.Ldfld, CompilerServices.fiDSCNewDS);
@@ -728,7 +735,7 @@ namespace Crow
//store template bindings in instanciator
templateBinding = dm.CreateDelegate (typeof(EventHandler<ValueChangeEventArgs>));
- #region emit ParentChanged method
+ #region emit LogicalParentChanged method
//load new parent onto the stack for handler addition
ilPC.Emit (OpCodes.Ldarg_2);
@@ -749,7 +756,7 @@ namespace Crow
cachedDelegates.Add(dmPC.CreateDelegate (CompilerServices.ehTypeDSChange, this));
#endregion
- ctx.emitCachedDelegateHandlerAddition(delDSIndex, typeof(GraphicObject).GetEvent("ParentChanged"));
+ ctx.emitCachedDelegateHandlerAddition(delDSIndex, typeof(GraphicObject).GetEvent("LogicalParentChanged"));
}
/// <summary>
/// create the valuechanged handler, the datasourcechanged handler and emit event handling
@@ -956,7 +963,7 @@ namespace Crow
#endregion
/// <summary> Emits remove old data source event handler./summary>
- void emitRemoveOldDataSourceHandler(ILGenerator il, string eventName, string delegateName){
+ void emitRemoveOldDataSourceHandler(ILGenerator il, string eventName, string delegateName, bool DSSide = true){
System.Reflection.Emit.Label cancel = il.DefineLabel ();
il.Emit (OpCodes.Ldarg_2);//load old parent
@@ -964,8 +971,11 @@ namespace Crow
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"));
+ if (DSSide){//event is defined in the dataSource instance
+ il.Emit (OpCodes.Ldarg_2);//1st arg load old datasource
+ il.Emit (OpCodes.Ldfld, typeof (DataSourceChangeEventArgs).GetField ("OldDataSource"));
+ }else//the event is in the source
+ il.Emit (OpCodes.Ldarg_1);//1st arg load old datasource
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("RemoveEventHandlerByName", BindingFlags.Static | BindingFlags.Public));
diff --git a/src/Interface.cs b/src/Interface.cs
index 941b96f9..6547b0e5 100644
--- a/src/Interface.cs
+++ b/src/Interface.cs
@@ -518,6 +518,7 @@ namespace Crow
//TODO:parent is not reset to null because object will be added
//to ObjectToRedraw list, and without parent, it fails
GraphicObject g = GraphicTree [i];
+ g.DataSource = null;
g.Visible = false;
GraphicTree.RemoveAt (0);
}