mirror of https://github.com/AMT-Cheif/Stylet.git
Add support for DependencyPropertyChangedEventHandler to EventAction
This commit is contained in:
parent
9a5143c343
commit
51007f4a22
|
@ -14,7 +14,11 @@ namespace Stylet.Xaml
|
|||
public class EventAction : ActionBase
|
||||
{
|
||||
private static readonly ILogger logger = LogManager.GetLogger(typeof(EventAction));
|
||||
private static readonly MethodInfo invokeCommandMethodInfo = typeof(EventAction).GetMethod("InvokeCommand", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
private static readonly MethodInfo[] invokeCommandMethodInfos = new[]
|
||||
{
|
||||
typeof(EventAction).GetMethod("InvokeEventArgsCommand", BindingFlags.NonPublic | BindingFlags.Instance),
|
||||
typeof(EventAction).GetMethod("InvokeDependencyCommand", BindingFlags.NonPublic | BindingFlags.Instance),
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Type of event handler
|
||||
|
@ -49,8 +53,8 @@ namespace Stylet.Xaml
|
|||
{
|
||||
var methodParameters = targetMethodInfo.GetParameters();
|
||||
if (!(methodParameters.Length == 0 ||
|
||||
(methodParameters.Length == 1 && typeof(EventArgs).IsAssignableFrom(methodParameters[0].ParameterType)) ||
|
||||
(methodParameters.Length == 2 && typeof(EventArgs).IsAssignableFrom(methodParameters[1].ParameterType))))
|
||||
(methodParameters.Length == 1 && (typeof(EventArgs).IsAssignableFrom(methodParameters[0].ParameterType) || methodParameters[0].ParameterType == typeof(DependencyPropertyChangedEventArgs))) ||
|
||||
(methodParameters.Length == 2 && (typeof(EventArgs).IsAssignableFrom(methodParameters[1].ParameterType) || methodParameters[1].ParameterType == typeof(DependencyPropertyChangedEventArgs)))))
|
||||
{
|
||||
var e = new ActionSignatureInvalidException(String.Format("Method {0} on {1} must have the signatures void Method(), void Method(EventArgsOrSubClass e), or void Method(object sender, EventArgsOrSubClass e)", this.MethodName, newTargetType.Name));
|
||||
logger.Error(e);
|
||||
|
@ -64,18 +68,40 @@ namespace Stylet.Xaml
|
|||
/// <returns>An event hander, which, when invoked, will invoke the action</returns>
|
||||
public Delegate GetDelegate()
|
||||
{
|
||||
var del = Delegate.CreateDelegate(this.eventHandlerType, this, invokeCommandMethodInfo, false);
|
||||
Delegate del = null;
|
||||
foreach (var invokeCommandMethodInfo in invokeCommandMethodInfos)
|
||||
{
|
||||
del = Delegate.CreateDelegate(this.eventHandlerType, this, invokeCommandMethodInfo, false);
|
||||
if (del != null)
|
||||
break;
|
||||
}
|
||||
|
||||
if (del == null)
|
||||
{
|
||||
var e = new ActionEventSignatureInvalidException(String.Format("Event being bound to does not have the '(object sender, EventArgsOrSubclass e)' signature we were expecting. Method {0} on target {1}", this.MethodName, this.Target));
|
||||
var msg = String.Format("Event being bound to does not have a signature we know about. Method {0} on target {1}. Valid signatures are:" +
|
||||
"Valid signatures are:\n" +
|
||||
" - '(object sender, EventArgsOrSubclass e)'\n" +
|
||||
" - '(object sender, DependencyPropertyChangedEventArgs e)'", this.MethodName, this.Target);
|
||||
var e = new ActionEventSignatureInvalidException(msg);
|
||||
logger.Error(e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
return del;
|
||||
}
|
||||
|
||||
private void InvokeDependencyCommand(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
this.InvokeCommand(sender, e);
|
||||
}
|
||||
|
||||
private void InvokeEventArgsCommand(object sender, EventArgs e)
|
||||
{
|
||||
this.InvokeCommand(sender, e);
|
||||
}
|
||||
|
||||
// ReSharper disable once UnusedMember.Local
|
||||
private void InvokeCommand(object sender, EventArgs e)
|
||||
private void InvokeCommand(object sender, object e)
|
||||
{
|
||||
// If we've made it this far and the target is still the default, then something's wrong
|
||||
// Make sure they know
|
||||
|
@ -83,7 +109,7 @@ namespace Stylet.Xaml
|
|||
{
|
||||
var ex = new ActionNotSetException(String.Format("View.ActionTarget not on control {0} (method {1}). " +
|
||||
"This probably means the control hasn't inherited it from a parent, e.g. because a ContextMenu or Popup sits in the visual tree. " +
|
||||
"You will need so set 's:View.ActionTarget' explicitly. See the wiki for more details.", this.Subject, this.MethodName));
|
||||
"You will need so set 's:View.ActionTarget' explicitly. See the wiki section \"Actions\" for more details.", this.Subject, this.MethodName));
|
||||
logger.Error(ex);
|
||||
throw ex;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace StyletUnitTests
|
|||
#pragma warning disable 0067
|
||||
public event EventHandler SimpleEventHandler;
|
||||
public event Action BadEventHandler;
|
||||
public event DependencyPropertyChangedEventHandler DependencyChangedEventHandler;
|
||||
#pragma warning restore 0067
|
||||
}
|
||||
|
||||
|
@ -57,6 +58,18 @@ namespace StyletUnitTests
|
|||
this.EventArgs = e;
|
||||
}
|
||||
|
||||
public DependencyPropertyChangedEventArgs DependencyChangedEventArgs;
|
||||
public void DoSomethingWithDependencyChangedEventArgs(DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
this.DependencyChangedEventArgs = e;
|
||||
}
|
||||
|
||||
public void DoSomethingWithObjectAndDependencyChangedEventArgs(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
this.Sender = sender;
|
||||
this.DependencyChangedEventArgs = e;
|
||||
}
|
||||
|
||||
public void DoSomethingUnsuccessfully()
|
||||
{
|
||||
throw new InvalidOperationException("foo");
|
||||
|
@ -70,6 +83,7 @@ namespace StyletUnitTests
|
|||
private DependencyObject subject;
|
||||
private Target target;
|
||||
private EventInfo eventInfo;
|
||||
private EventInfo dependencyChangedEventInfo;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
|
@ -77,6 +91,7 @@ namespace StyletUnitTests
|
|||
this.target = new Target();
|
||||
this.subject = new Subject();
|
||||
this.eventInfo = typeof(Subject).GetEvent("SimpleEventHandler");
|
||||
this.dependencyChangedEventInfo = typeof(Subject).GetEvent("DependencyChangedEventHandler");
|
||||
View.SetActionTarget(this.subject, this.target);
|
||||
}
|
||||
|
||||
|
@ -175,6 +190,27 @@ namespace StyletUnitTests
|
|||
Assert.AreEqual(arg, this.target.EventArgs);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InvokingCommandCallsMethodWithDependencyChangedEventArgs()
|
||||
{
|
||||
var cmd = new EventAction(this.subject, this.dependencyChangedEventInfo.EventHandlerType, "DoSomethingWithDependencyChangedEventArgs", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
var arg = new DependencyPropertyChangedEventArgs();
|
||||
cmd.GetDelegate().DynamicInvoke(null, arg);
|
||||
Assert.AreEqual(arg, this.target.DependencyChangedEventArgs);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InvokingCommandCallsMethodWithSenderAndDependencyChangedEventArgs()
|
||||
{
|
||||
var cmd = new EventAction(this.subject, this.dependencyChangedEventInfo.EventHandlerType, "DoSomethingWithObjectAndDependencyChangedEventArgs", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
var sender = new object();
|
||||
var arg = new DependencyPropertyChangedEventArgs();
|
||||
cmd.GetDelegate().DynamicInvoke(sender, arg);
|
||||
|
||||
Assert.AreEqual(sender, this.target.Sender);
|
||||
Assert.AreEqual(arg, this.target.DependencyChangedEventArgs);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BadEventHandlerSignatureThrows()
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue