state.Value = obj;
state.IsInstantiated = true;
}
+ root_state = state;
}
object_states.Push (state);
if (!state.Type.IsContentValue (service_provider))
throw new XamlObjectWriterException (String.Format ("Event {0} has no underlying member to attach event", member));
int idx = value.LastIndexOf ('.');
- var xt = idx < 0 ? member.DeclaringType : ResolveTypeFromName (value.Substring (0, idx));
+ var xt = idx < 0 ? root_state.Type : ResolveTypeFromName (value.Substring (0, idx));
if (xt == null)
throw new XamlObjectWriterException (String.Format ("Referenced type {0} in event {1} was not found", value, member));
if (xt.UnderlyingType == null)
// get an appropriate MethodInfo overload whose signature matches the event's handler type.
// FIXME: this may need more strict match. RuntimeBinder may be useful here.
var eventMethodParams = ev.EventHandlerType.GetMethod ("Invoke").GetParameters ();
- var mi = xt.UnderlyingType.GetMethod (mn, (from pi in eventMethodParams select pi.ParameterType).ToArray ());
+
+ var target = root_state.Value;
+ var mi = target.GetType().GetMethod (mn, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, (from pi in eventMethodParams select pi.ParameterType).ToArray (), null);
if (mi == null)
throw new XamlObjectWriterException (String.Format ("Referenced value method {0} in type {1} indicated by event {2} was not found", mn, value, member));
var obj = object_states.Peek ().Value;
- ev.AddEventHandler (obj, Delegate.CreateDelegate (ev.EventHandlerType, obj, mi));
+ ev.AddEventHandler (obj, Delegate.CreateDelegate (ev.EventHandlerType, target, mi));
}
void SetValue (XamlMember member, object value)
internal IValueSerializerContext service_provider;
+ internal ObjectState root_state;
internal Stack<ObjectState> object_states = new Stack<ObjectState> ();
internal PrefixLookup prefix_lookup {
get { return (PrefixLookup) service_provider.GetService (typeof (INamespacePrefixLookup)); }
#endregion
}
+#region "xamarin bug #2927"
+namespace XamarinBug2927
+{
+ public class RootClass
+ {
+ public RootClass ()
+ {
+ Child = new MyChildClass ();
+ }
+
+ public bool Invoked;
+
+ public ChildClass Child { get; set; }
+ }
+
+ public class MyRootClass : RootClass
+ {
+ public void HandleMyEvent (object sender, EventArgs e)
+ {
+ Invoked = true;
+ }
+ }
+
+ public class RootClass2
+ {
+ public RootClass2 ()
+ {
+ Child = new MyChildClass ();
+ }
+
+ public bool Invoked;
+
+ public ChildClass Child { get; set; }
+
+ public void HandleMyEvent (object sender, EventArgs e)
+ {
+ Invoked = true;
+ }
+ }
+
+ public class MyRootClass2 : RootClass2
+ {
+ }
+
+ public class ChildClass
+ {
+ public bool Invoked;
+
+ public DescendantClass Descendant { get; set; }
+ }
+
+ public class MyChildClass : ChildClass
+ {
+ public MyChildClass ()
+ {
+ Descendant = new DescendantClass () { Value = "x" };
+ }
+
+ public void HandleMyEvent (object sender, EventArgs e)
+ {
+ Invoked = true;
+ }
+ }
+
+ public class DescendantClass
+ {
+ public bool Invoked;
+ public event EventHandler DoWork;
+ public string Value { get; set; }
+
+ public void Work ()
+ {
+ DoWork (this, EventArgs.Empty);
+ }
+
+ public void HandleMyEvent (object sender, EventArgs e)
+ {
+ Invoked = true;
+ }
+ }
+}
+#endregion
+
ow.Close ();
Assert.AreEqual (typeof (int), ow.Result, "#1");
}
+
+ [Test]
+ public void LookupCorrectEventBoundMethod ()
+ {
+ var o = (XamarinBug2927.MyRootClass) XamlServices.Load (GetReader ("LookupCorrectEvent.xml"));
+ o.Child.Descendant.Work ();
+ Assert.IsTrue (o.Invoked, "#1");
+ Assert.IsFalse (o.Child.Invoked, "#2");
+ Assert.IsFalse (o.Child.Descendant.Invoked, "#3");
+ }
+
+ [Test]
+ [ExpectedException (typeof (XamlObjectWriterException))]
+ public void LookupCorrectEventBoundMethod2 ()
+ {
+ XamlServices.Load (GetReader ("LookupCorrectEvent2.xml"));
+ }
+
+ [Test]
+ public void LookupCorrectEventBoundMethod3 ()
+ {
+ XamlServices.Load (GetReader ("LookupCorrectEvent3.xml"));
+ }
// common use case based tests (to other readers/writers).
--- /dev/null
+<MyRootClass xmlns="clr-namespace:XamarinBug2927;assembly=System.Xaml_test_net_4_0" >
+ <MyRootClass.Child>
+ <MyChildClass>
+ <MyChildClass.Descendant>
+ <DescendantClass Value='x' DoWork='HandleMyEvent' />
+ </MyChildClass.Descendant>
+ </MyChildClass>
+ </MyRootClass.Child>
+</MyRootClass>
--- /dev/null
+<RootClass xmlns="clr-namespace:XamarinBug2927;assembly=System.Xaml_test_net_4_0" >
+ <RootClass.Child>
+ <MyChildClass>
+ <MyChildClass.Descendant>
+ <DescendantClass Value='x' DoWork='HandleMyEvent' />
+ </MyChildClass.Descendant>
+ </MyChildClass>
+ </RootClass.Child>
+</RootClass>
--- /dev/null
+<MyRootClass2 xmlns="clr-namespace:XamarinBug2927;assembly=System.Xaml_test_net_4_0" >
+ <MyRootClass2.Child>
+ <MyChildClass>
+ <MyChildClass.Descendant>
+ <DescendantClass Value='x' DoWork='HandleMyEvent' />
+ </MyChildClass.Descendant>
+ </MyChildClass>
+ </MyRootClass2.Child>
+</MyRootClass2>