diff options
-rw-r--r-- | Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs | 14 | ||||
-rw-r--r-- | Xamarin.Forms.Xaml.UnitTests/EventsConnection.xaml | 2 | ||||
-rw-r--r-- | Xamarin.Forms.Xaml.UnitTests/EventsConnection.xaml.cs | 37 |
3 files changed, 52 insertions, 1 deletions
diff --git a/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs b/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs index 71f19f56..16eddb41 100644 --- a/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs +++ b/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs @@ -316,7 +316,12 @@ namespace Xamarin.Forms.Build.Tasks //If the target is an event, connect // IL_0007: ldloc.0 // IL_0008: ldarg.0 + // // IL_0009: ldftn instance void class Xamarin.Forms.Xaml.XamlcTests.MyPage::OnButtonClicked(object, class [mscorlib]System.EventArgs) + //OR, if the handler is virtual + // IL_000x: ldarg.0 + // IL_0009: ldvirtftn instance void class Xamarin.Forms.Xaml.XamlcTests.MyPage::OnButtonClicked(object, class [mscorlib]System.EventArgs) + // // IL_000f: newobj instance void class [mscorlib]System.EventHandler::'.ctor'(object, native int) // IL_0014: callvirt instance void class [Xamarin.Forms.Core]Xamarin.Forms.Button::add_Clicked(class [mscorlib]System.EventHandler) @@ -345,7 +350,14 @@ namespace Xamarin.Forms.Build.Tasks string.Format("EventHandler \"{0}\" not found in type \"{1}\"", value, context.Body.Method.DeclaringType.FullName), iXmlLineInfo); } - context.IL.Emit(OpCodes.Ldftn, handler); + if (handler.IsVirtual) + { + context.IL.Emit(OpCodes.Ldarg_0); + context.IL.Emit(OpCodes.Ldvirtftn, handler); + } + else + context.IL.Emit(OpCodes.Ldftn, handler); + //FIXME: eventually get the right ctor instead fo the First() one, just in case another one could exists (not even sure it's possible). var ctor = module.Import(eventinfo.EventType.Resolve().GetConstructors().First()); ctor = ctor.ResolveGenericParameters(eventinfo.EventType, module); diff --git a/Xamarin.Forms.Xaml.UnitTests/EventsConnection.xaml b/Xamarin.Forms.Xaml.UnitTests/EventsConnection.xaml index f9032089..7e48e1bb 100644 --- a/Xamarin.Forms.Xaml.UnitTests/EventsConnection.xaml +++ b/Xamarin.Forms.Xaml.UnitTests/EventsConnection.xaml @@ -12,5 +12,7 @@ Clicked="HandleClickedOnBase" /> <local:ElementWithEvent x:Name="elementwithAsyncprivateHandler" Clicked="HandleClickedPrivateAsync" /> + <local:ElementWithEvent x:Name="elementWithVirtualHandler" + Clicked="HandleVirtualClicked" /> </StackLayout> </local:BaseForEvents>
\ No newline at end of file diff --git a/Xamarin.Forms.Xaml.UnitTests/EventsConnection.xaml.cs b/Xamarin.Forms.Xaml.UnitTests/EventsConnection.xaml.cs index 5727693e..3552fa21 100644 --- a/Xamarin.Forms.Xaml.UnitTests/EventsConnection.xaml.cs +++ b/Xamarin.Forms.Xaml.UnitTests/EventsConnection.xaml.cs @@ -71,6 +71,12 @@ namespace Xamarin.Forms.Xaml.UnitTests asyncPrivateClicked++; } + int baseForVirtualClicked; + protected virtual void HandleVirtualClicked(object sender, EventArgs e) + { + baseForVirtualClicked++; + } + [TestFixture] public class Tests { @@ -113,6 +119,37 @@ namespace Xamarin.Forms.Xaml.UnitTests layout.elementwithAsyncprivateHandler.SendClicked (); Assert.AreEqual (1, layout.asyncPrivateClicked); } + + [TestCase(false)] + [TestCase(true)] + public void TestVirtualHandler(bool useCompiledXaml) + { + var layout = new SubForEvents(useCompiledXaml); + Assert.AreEqual(0, layout.baseForVirtualClicked); + Assert.AreEqual(0, layout.overrideClicked); + layout.elementWithVirtualHandler.SendClicked(); + Assert.AreEqual(0, layout.baseForVirtualClicked); + Assert.AreEqual(1, layout.overrideClicked); + } + } + } + + public class SubForEvents : EventsConnection + { + public SubForEvents(bool useCompiledXaml) : base(useCompiledXaml) + { + } + + public int overrideClicked; + protected override void HandleVirtualClicked(object sender, EventArgs e) + { + overrideClicked++; + } + +#pragma warning disable 1998 // considered for removal + async void HandleClickedPrivateAsync(object sender, EventArgs e) +#pragma warning restore 1998 + { } } }
\ No newline at end of file |