diff --git a/Stylet/Xaml/ActionBase.cs b/Stylet/Xaml/ActionBase.cs index a514c45..783a4ee 100644 --- a/Stylet/Xaml/ActionBase.cs +++ b/Stylet/Xaml/ActionBase.cs @@ -42,7 +42,7 @@ namespace Stylet.Xaml protected readonly ActionUnavailableBehaviour ActionNonExistentBehaviour; /// - /// Gets the object on which methods will be invokced + /// Gets the object on which methods will be invoked /// public object Target { @@ -128,10 +128,19 @@ namespace Stylet.Xaml } else { - var newTargetType = newTarget.GetType(); + BindingFlags bindingFlags; + if (newTarget is Type newTargetType) + { + bindingFlags = BindingFlags.Public | BindingFlags.Static; + } + else + { + newTargetType = newTarget.GetType(); + bindingFlags = BindingFlags.Public | BindingFlags.Instance; + } try { - targetMethodInfo = newTargetType.GetMethod(this.MethodName); + targetMethodInfo = newTargetType.GetMethod(this.MethodName, bindingFlags); if (targetMethodInfo == null) this.logger.Warn("Unable to find method {0} on {1}", this.MethodName, newTargetType.Name); @@ -199,7 +208,8 @@ namespace Stylet.Xaml try { - this.TargetMethodInfo.Invoke(this.Target, parameters); + var target = this.TargetMethodInfo.IsStatic ? null : this.Target; + this.TargetMethodInfo.Invoke(target, parameters); } catch (TargetInvocationException e) { diff --git a/StyletUnitTests/CommandActionTests.cs b/StyletUnitTests/CommandActionTests.cs index 9718b1f..731ed36 100644 --- a/StyletUnitTests/CommandActionTests.cs +++ b/StyletUnitTests/CommandActionTests.cs @@ -2,6 +2,7 @@ using Stylet; using Stylet.Xaml; using System; +using System.Runtime.CompilerServices; using System.Windows; namespace StyletUnitTests @@ -68,6 +69,12 @@ namespace StyletUnitTests public void DoSomething() { } } + public class StaticTarget + { + public static bool DidSomething; + public static void DoSomething() => DidSomething = true; + } + private DependencyObject subject; private Target target; @@ -77,6 +84,7 @@ namespace StyletUnitTests this.target = new Target(); this.subject = new DependencyObject(); View.SetActionTarget(this.subject, this.target); + StaticTarget.DidSomething = false; } [Test] @@ -315,5 +323,16 @@ namespace StyletUnitTests cmd.Execute(null); Assert.IsTrue(this.target.DoSomethingCalled); } + + [Test] + public void SupportsStaticTargets() + { + var cmd = new CommandAction(this.subject, null, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw); + View.SetActionTarget(this.subject, typeof(StaticTarget)); + + Assert.True(cmd.CanExecute(null)); + cmd.Execute(null); + Assert.True(StaticTarget.DidSomething); + } } } diff --git a/StyletUnitTests/EventActionTests.cs b/StyletUnitTests/EventActionTests.cs index ab18b59..7c2c7c5 100644 --- a/StyletUnitTests/EventActionTests.cs +++ b/StyletUnitTests/EventActionTests.cs @@ -74,6 +74,12 @@ namespace StyletUnitTests { } + public class StaticTarget + { + public static bool DidSomething; + public static void DoSomething() => DidSomething = true; + } + private DependencyObject subject; private Target target; private EventInfo eventInfo; @@ -87,6 +93,7 @@ namespace StyletUnitTests this.eventInfo = typeof(Subject).GetEvent("SimpleEventHandler"); this.dependencyChangedEventInfo = typeof(Subject).GetEvent("DependencyChangedEventHandler"); View.SetActionTarget(this.subject, this.target); + StaticTarget.DidSomething = false; } [Test] @@ -269,13 +276,23 @@ namespace StyletUnitTests { var view = new DependencyObject(); var backupView = new DependencyObject(); - var cmd = new CommandAction(view, backupView, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw); + var cmd = new EventAction(view, backupView, this.eventInfo.EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw); View.SetActionTarget(backupView, this.target); view.SetValue(FrameworkElement.DataContextProperty, this.target); - cmd.Execute(null); + cmd.GetDelegate().DynamicInvoke(null, null); Assert.IsTrue(this.target.DoSomethingCalled); } + + [Test] + public void SupportsStaticTargets() + { + var cmd = new EventAction(this.subject, null, this.eventInfo.EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw); + View.SetActionTarget(this.subject, typeof(StaticTarget)); + + cmd.GetDelegate().DynamicInvoke(null, null); + Assert.True(StaticTarget.DidSomething); + } } }