From 48064a528d73d0b3706fbfa6b5ae0cafd0afb0c4 Mon Sep 17 00:00:00 2001 From: Laurent Bugnion Date: Wed, 20 Apr 2016 23:38:18 +0200 Subject: [PATCH] Modified SetCommand to allow avoiding explicit type parameter when using an Android CheckBox and the default CheckedChange event. --- .../Helpers/Extensions.cs | 26 +---- .../Helpers/ExtensionsAndroid.cs | 98 +++++++++++++++++++ .../Helpers/ExtensionsApple.cs | 57 +++++++++++ .../AndroidTestApp/Binding/SetCommandTest.cs | 10 +- 4 files changed, 163 insertions(+), 28 deletions(-) diff --git a/GalaSoft.MvvmLight/GalaSoft.MvvmLight.Platform (Android)/Helpers/Extensions.cs b/GalaSoft.MvvmLight/GalaSoft.MvvmLight.Platform (Android)/Helpers/Extensions.cs index f571043..bd0a6c0 100644 --- a/GalaSoft.MvvmLight/GalaSoft.MvvmLight.Platform (Android)/Helpers/Extensions.cs +++ b/GalaSoft.MvvmLight/GalaSoft.MvvmLight.Platform (Android)/Helpers/Extensions.cs @@ -272,15 +272,7 @@ namespace GalaSoft.MvvmLight.Helpers var castedBinding = (Binding)commandParameterBinding; - EventHandler handler = (s, args) => - { - var param = castedBinding == null ? default(T) : castedBinding.Value; - - if (command.CanExecute(param)) - { - command.Execute(param); - } - }; + var handler = e.GetCommandHandler(eventName, t, command, castedBinding); e.AddEventHandler( element, @@ -378,13 +370,7 @@ namespace GalaSoft.MvvmLight.Helpers var t = element.GetType(); var e = t.GetEventInfoForControl(eventName); - EventHandler handler = (s, args) => - { - if (command.CanExecute(null)) - { - command.Execute(null); - } - }; + var handler = e.GetCommandHandler(eventName, t, command); e.AddEventHandler( element, @@ -460,13 +446,7 @@ namespace GalaSoft.MvvmLight.Helpers var t = element.GetType(); var e = t.GetEventInfoForControl(eventName); - EventHandler handler = (s, args) => - { - if (command.CanExecute(commandParameter)) - { - command.Execute(commandParameter); - } - }; + var handler = e.GetCommandHandler(eventName, t, command, commandParameter); e.AddEventHandler( element, diff --git a/GalaSoft.MvvmLight/GalaSoft.MvvmLight.Platform (Android)/Helpers/ExtensionsAndroid.cs b/GalaSoft.MvvmLight/GalaSoft.MvvmLight.Platform (Android)/Helpers/ExtensionsAndroid.cs index 3c60385..3dd8a58 100644 --- a/GalaSoft.MvvmLight/GalaSoft.MvvmLight.Platform (Android)/Helpers/ExtensionsAndroid.cs +++ b/GalaSoft.MvvmLight/GalaSoft.MvvmLight.Platform (Android)/Helpers/ExtensionsAndroid.cs @@ -16,8 +16,11 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Reflection; +using System.Windows.Input; using Android.Views; using Android.Widget; +using GalaSoft.MvvmLight.Command; namespace GalaSoft.MvvmLight.Helpers { @@ -84,5 +87,100 @@ namespace GalaSoft.MvvmLight.Helpers return eventName; } + + internal static Delegate GetCommandHandler( + this EventInfo info, + string eventName, + Type elementType, + ICommand command) + { + Delegate result; + + if (string.IsNullOrEmpty(eventName) + && elementType == typeof (CheckBox)) + { + EventHandler handler = (s, args) => + { + if (command.CanExecute(null)) + { + command.Execute(null); + } + }; + + result = handler; + } + else + { + EventHandler handler = (s, args) => + { + if (command.CanExecute(null)) + { + command.Execute(null); + } + }; + + result = handler; + } + + return result; + } + + internal static Delegate GetCommandHandler( + this EventInfo info, + string eventName, + Type elementType, + RelayCommand command, + Binding castedBinding) + { + Delegate result; + + if (string.IsNullOrEmpty(eventName) + && elementType == typeof(CheckBox)) + { + EventHandler handler = (s, args) => + { + var param = castedBinding == null ? default(T) : castedBinding.Value; + command.Execute(param); + }; + + result = handler; + } + else + { + EventHandler handler = (s, args) => + { + var param = castedBinding == null ? default(T) : castedBinding.Value; + command.Execute(param); + }; + + result = handler; + } + + return result; + } + + internal static Delegate GetCommandHandler( + this EventInfo info, + string eventName, + Type elementType, + RelayCommand command, + T commandParameter) + { + Delegate result; + + if (string.IsNullOrEmpty(eventName) + && elementType == typeof(CheckBox)) + { + EventHandler handler = (s, args) => command.Execute(commandParameter); + result = handler; + } + else + { + EventHandler handler = (s, args) => command.Execute(commandParameter); + result = handler; + } + + return result; + } } } \ No newline at end of file diff --git a/GalaSoft.MvvmLight/GalaSoft.MvvmLight.Platform (iOS)/Helpers/ExtensionsApple.cs b/GalaSoft.MvvmLight/GalaSoft.MvvmLight.Platform (iOS)/Helpers/ExtensionsApple.cs index ea721a3..5f0b480 100644 --- a/GalaSoft.MvvmLight/GalaSoft.MvvmLight.Platform (iOS)/Helpers/ExtensionsApple.cs +++ b/GalaSoft.MvvmLight/GalaSoft.MvvmLight.Platform (iOS)/Helpers/ExtensionsApple.cs @@ -16,7 +16,10 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Reflection; +using System.Windows.Input; using Foundation; +using GalaSoft.MvvmLight.Command; using UIKit; namespace GalaSoft.MvvmLight.Helpers @@ -349,5 +352,59 @@ namespace GalaSoft.MvvmLight.Helpers return eventName; } + + + internal static Delegate GetCommandHandler( + this EventInfo info, + string eventName, + Type elementType, + ICommand command) + { + // At the moment, all supported controls with default events + // in iOS are using EventHandler, and not EventHandler<...>. + + EventHandler handler = (s, args) => + { + if (command.CanExecute(null)) + { + command.Execute(null); + } + }; + + return handler; + } + + internal static Delegate GetCommandHandler( + this EventInfo info, + string eventName, + Type elementType, + RelayCommand command, + Binding castedBinding) + { + // At the moment, all supported controls with default events + // in iOS are using EventHandler, and not EventHandler<...>. + + EventHandler handler = (s, args) => + { + var param = castedBinding == null ? default(T) : castedBinding.Value; + command.Execute(param); + }; + + return handler; + } + + internal static Delegate GetCommandHandler( + this EventInfo info, + string eventName, + Type elementType, + RelayCommand command, + T commandParameter) + { + // At the moment, all supported controls with default events + // in iOS are using EventHandler, and not EventHandler<...>. + + EventHandler handler = (s, args) => command.Execute(commandParameter); + return handler; + } } } \ No newline at end of file diff --git a/GalaSoft.MvvmLight/Tests/AndroidTestApp/Binding/SetCommandTest.cs b/GalaSoft.MvvmLight/Tests/AndroidTestApp/Binding/SetCommandTest.cs index a022bca..60ae149 100644 --- a/GalaSoft.MvvmLight/Tests/AndroidTestApp/Binding/SetCommandTest.cs +++ b/GalaSoft.MvvmLight/Tests/AndroidTestApp/Binding/SetCommandTest.cs @@ -207,7 +207,7 @@ namespace GalaSoft.MvvmLight.Test.Binding } [Test] - public void SetCommand_OnCheckBoxNoValueNoEventName_ClickEventShouldBeUsed() + public void SetCommand_OnCheckBoxNoValueNoEventName_CheckedChangeEventShouldBeUsed() { var value = DateTime.Now.Ticks.ToString(); var vmTarget = new TestViewModel(); @@ -215,7 +215,7 @@ namespace GalaSoft.MvvmLight.Test.Binding var checkBox = new CheckBox(Application.Context); - checkBox.SetCommand(vmTarget.SetPropertyWithoutValueCommand); + checkBox.SetCommand(vmTarget.SetPropertyWithoutValueCommand); Assert.IsNull(vmTarget.TargetProperty); checkBox.PerformClick(); @@ -279,7 +279,7 @@ namespace GalaSoft.MvvmLight.Test.Binding vmSource, () => vmSource.Model.MyProperty); - checkBox.SetCommand( + checkBox.SetCommand( vmTarget.SetPropertyCommand, _binding); @@ -319,7 +319,7 @@ namespace GalaSoft.MvvmLight.Test.Binding var checkBox = new CheckBox(Application.Context); - checkBox.SetCommand( + checkBox.SetCommand( vmTarget.SetPropertyCommand, value); @@ -379,7 +379,7 @@ namespace GalaSoft.MvvmLight.Test.Binding var vmTarget = new TestViewModel(); var checkBox = new CheckBox(Application.Context); - checkBox.SetCommand(vmTarget.TestCommandImpl); + checkBox.SetCommand(vmTarget.TestCommandImpl); var castedCommand = (CommandImpl)vmTarget.TestCommandImpl;