mirror of https://github.com/AMT-Cheif/Stylet.git
Implement another mechanism of backup ActionTarget, using IRootObjectProvider
This commit is contained in:
parent
54cd9cf18f
commit
fdfaefa94e
|
@ -4,6 +4,8 @@ using System.Reflection;
|
|||
using System.Runtime.ExceptionServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Globalization;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Stylet.Xaml
|
||||
{
|
||||
|
@ -57,11 +59,12 @@ namespace Stylet.Xaml
|
|||
/// Initialises a new instance of the <see cref="ActionBase"/> class
|
||||
/// </summary>
|
||||
/// <param name="subject">View to grab the View.ActionTarget from</param>
|
||||
/// <param name="backupSubject">Backup subject to use if no ActionTarget could be retrieved from the subject</param>
|
||||
/// <param name="methodName">Method name. the MyMethod in Buttom Command="{s:Action MyMethod}".</param>
|
||||
/// <param name="targetNullBehaviour">Behaviour for it the relevant View.ActionTarget is null</param>
|
||||
/// <param name="actionNonExistentBehaviour">Behaviour for if the action doesn't exist on the View.ActionTarget</param>
|
||||
/// <param name="logger">Logger to use</param>
|
||||
public ActionBase(DependencyObject subject, string methodName, ActionUnavailableBehaviour targetNullBehaviour, ActionUnavailableBehaviour actionNonExistentBehaviour, ILogger logger)
|
||||
public ActionBase(DependencyObject subject, DependencyObject backupSubject, string methodName, ActionUnavailableBehaviour targetNullBehaviour, ActionUnavailableBehaviour actionNonExistentBehaviour, ILogger logger)
|
||||
{
|
||||
this.Subject = subject;
|
||||
this.MethodName = methodName;
|
||||
|
@ -69,13 +72,30 @@ namespace Stylet.Xaml
|
|||
this.ActionNonExistentBehaviour = actionNonExistentBehaviour;
|
||||
this.logger = logger;
|
||||
|
||||
var binding = new Binding()
|
||||
var actionTargetBinding = new Binding()
|
||||
{
|
||||
Path = new PropertyPath(View.ActionTargetProperty),
|
||||
Mode = BindingMode.OneWay,
|
||||
Source = this.Subject,
|
||||
};
|
||||
BindingOperations.SetBinding(this, targetProperty, binding);
|
||||
|
||||
if (backupSubject == null)
|
||||
{
|
||||
BindingOperations.SetBinding(this, targetProperty, actionTargetBinding);
|
||||
}
|
||||
else
|
||||
{
|
||||
var multiBinding = new MultiBinding();
|
||||
multiBinding.Converter = new MultiBindingToActionTargetConverter();
|
||||
multiBinding.Bindings.Add(actionTargetBinding);
|
||||
multiBinding.Bindings.Add(new Binding()
|
||||
{
|
||||
Path = new PropertyPath(View.ActionTargetProperty),
|
||||
Mode = BindingMode.OneWay,
|
||||
Source = backupSubject,
|
||||
});
|
||||
BindingOperations.SetBinding(this, targetProperty, multiBinding);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateActionTarget(object oldTarget, object newTarget)
|
||||
|
@ -178,5 +198,26 @@ namespace Stylet.Xaml
|
|||
ExceptionDispatchInfo.Capture(e.InnerException).Throw();
|
||||
}
|
||||
}
|
||||
|
||||
private class MultiBindingToActionTargetConverter : IMultiValueConverter
|
||||
{
|
||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
Debug.Assert(values.Length == 2);
|
||||
|
||||
if (values[0] != View.InitialActionTarget)
|
||||
return values[0];
|
||||
|
||||
if (values[1] != View.InitialActionTarget)
|
||||
return values[1];
|
||||
|
||||
return View.InitialActionTarget;
|
||||
}
|
||||
|
||||
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Reflection;
|
|||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Xaml;
|
||||
|
||||
namespace Stylet.Xaml
|
||||
{
|
||||
|
@ -106,17 +107,22 @@ namespace Stylet.Xaml
|
|||
if (!(valueService.TargetObject is DependencyObject))
|
||||
return this;
|
||||
|
||||
var targetObject = (DependencyObject)valueService.TargetObject;
|
||||
|
||||
var rootObjectProvider = (IRootObjectProvider)serviceProvider.GetService(typeof(IRootObjectProvider));
|
||||
var rootObject = rootObjectProvider == null ? null : rootObjectProvider.RootObject as DependencyObject;
|
||||
|
||||
var propertyAsDependencyProperty = valueService.TargetProperty as DependencyProperty;
|
||||
if (propertyAsDependencyProperty != null && propertyAsDependencyProperty.PropertyType == typeof(ICommand))
|
||||
{
|
||||
// If they're in design mode and haven't set View.ActionTarget, default to looking sensible
|
||||
return new CommandAction((DependencyObject)valueService.TargetObject, this.Method, this.CommandNullTargetBehaviour, this.CommandActionNotFoundBehaviour);
|
||||
return new CommandAction(targetObject, rootObject, this.Method, this.CommandNullTargetBehaviour, this.CommandActionNotFoundBehaviour);
|
||||
}
|
||||
|
||||
var propertyAsEventInfo = valueService.TargetProperty as EventInfo;
|
||||
if (propertyAsEventInfo != null)
|
||||
{
|
||||
var ec = new EventAction((DependencyObject)valueService.TargetObject, propertyAsEventInfo.EventHandlerType, this.Method, this.EventNullTargetBehaviour, this.EventActionNotFoundBehaviour);
|
||||
var ec = new EventAction(targetObject, rootObject, propertyAsEventInfo.EventHandlerType, this.Method, this.EventNullTargetBehaviour, this.EventActionNotFoundBehaviour);
|
||||
return ec.GetDelegate();
|
||||
}
|
||||
|
||||
|
@ -127,7 +133,7 @@ namespace Stylet.Xaml
|
|||
var parameters = propertyAsMethodInfo.GetParameters();
|
||||
if (parameters.Length == 2 && typeof(Delegate).IsAssignableFrom(parameters[1].ParameterType))
|
||||
{
|
||||
var ec = new EventAction((DependencyObject)valueService.TargetObject, parameters[1].ParameterType, this.Method, this.EventNullTargetBehaviour, this.EventActionNotFoundBehaviour);
|
||||
var ec = new EventAction(targetObject, rootObject, parameters[1].ParameterType, this.Method, this.EventNullTargetBehaviour, this.EventActionNotFoundBehaviour);
|
||||
return ec.GetDelegate();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,11 +29,12 @@ namespace Stylet.Xaml
|
|||
/// Initialises a new instance of the <see cref="CommandAction"/> class
|
||||
/// </summary>
|
||||
/// <param name="subject">View to grab the View.ActionTarget from</param>
|
||||
/// <param name="backupSubject">Backup subject to use if no ActionTarget could be retrieved from the subject</param>
|
||||
/// <param name="methodName">Method name. the MyMethod in Buttom Command="{s:Action MyMethod}".</param>
|
||||
/// <param name="targetNullBehaviour">Behaviour for it the relevant View.ActionTarget is null</param>
|
||||
/// <param name="actionNonExistentBehaviour">Behaviour for if the action doesn't exist on the View.ActionTarget</param>
|
||||
public CommandAction(DependencyObject subject, string methodName, ActionUnavailableBehaviour targetNullBehaviour, ActionUnavailableBehaviour actionNonExistentBehaviour)
|
||||
: base(subject, methodName, targetNullBehaviour, actionNonExistentBehaviour, logger)
|
||||
public CommandAction(DependencyObject subject, DependencyObject backupSubject, string methodName, ActionUnavailableBehaviour targetNullBehaviour, ActionUnavailableBehaviour actionNonExistentBehaviour)
|
||||
: base(subject, backupSubject, methodName, targetNullBehaviour, actionNonExistentBehaviour, logger)
|
||||
{ }
|
||||
|
||||
private string GuardName
|
||||
|
|
|
@ -26,12 +26,13 @@ namespace Stylet.Xaml
|
|||
/// Initialises a new instance of the <see cref="EventAction"/> class
|
||||
/// </summary>
|
||||
/// <param name="subject">View whose View.ActionTarget we watch</param>
|
||||
/// <param name="backupSubject">Backup subject to use if no ActionTarget could be retrieved from the subject</param>
|
||||
/// <param name="eventHandlerType">Type of event handler we're returning a delegate for</param>
|
||||
/// <param name="methodName">The MyMethod in {s:Action MyMethod}, this is what we call when the event's fired</param>
|
||||
/// <param name="targetNullBehaviour">Behaviour for it the relevant View.ActionTarget is null</param>
|
||||
/// <param name="actionNonExistentBehaviour">Behaviour for if the action doesn't exist on the View.ActionTarget</param>
|
||||
public EventAction(DependencyObject subject, Type eventHandlerType, string methodName, ActionUnavailableBehaviour targetNullBehaviour, ActionUnavailableBehaviour actionNonExistentBehaviour)
|
||||
: base(subject, methodName, targetNullBehaviour, actionNonExistentBehaviour, logger)
|
||||
public EventAction(DependencyObject subject, DependencyObject backupSubject, Type eventHandlerType, string methodName, ActionUnavailableBehaviour targetNullBehaviour, ActionUnavailableBehaviour actionNonExistentBehaviour)
|
||||
: base(subject, backupSubject, methodName, targetNullBehaviour, actionNonExistentBehaviour, logger)
|
||||
{
|
||||
if (targetNullBehaviour == ActionUnavailableBehaviour.Disable)
|
||||
throw new ArgumentException("Setting NullTarget = Disable is unsupported when used on an Event");
|
||||
|
|
|
@ -12,12 +12,9 @@ namespace StyletIntegrationTests
|
|||
{
|
||||
private readonly IWindowManager windowManager;
|
||||
|
||||
public ChildViewModel ChildViewModel { get; private set; }
|
||||
|
||||
public ShellViewModel(IWindowManager windowManager)
|
||||
{
|
||||
this.windowManager = windowManager;
|
||||
this.ChildViewModel = new ChildViewModel(windowManager);
|
||||
|
||||
this.DisplayName = "ShellViewModel";
|
||||
}
|
||||
|
@ -68,18 +65,8 @@ namespace StyletIntegrationTests
|
|||
else
|
||||
this.windowManager.ShowMessageBox("Failure");
|
||||
}
|
||||
}
|
||||
|
||||
public class ChildViewModel
|
||||
{
|
||||
private readonly IWindowManager windowManager;
|
||||
|
||||
public ChildViewModel(IWindowManager windowManager)
|
||||
{
|
||||
this.windowManager = windowManager;
|
||||
}
|
||||
|
||||
public void Foo()
|
||||
public void ShowActionTargetSaved()
|
||||
{
|
||||
this.windowManager.ShowMessageBox("Success!");
|
||||
}
|
||||
|
|
|
@ -76,14 +76,14 @@ namespace StyletUnitTests
|
|||
[Test]
|
||||
public void ThrowsIfTargetNullBehaviourIsThrowAndTargetBecomesNull()
|
||||
{
|
||||
var cmd = new CommandAction(this.subject, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Disable);
|
||||
var cmd = new CommandAction(this.subject, null, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Disable);
|
||||
Assert.Throws<ActionTargetNullException>(() => View.SetActionTarget(this.subject, null));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DisablesIfTargetNullBehaviourIsDisableAndTargetIsNull()
|
||||
{
|
||||
var cmd = new CommandAction(this.subject, "DoSomething", ActionUnavailableBehaviour.Disable, ActionUnavailableBehaviour.Disable);
|
||||
var cmd = new CommandAction(this.subject, null, "DoSomething", ActionUnavailableBehaviour.Disable, ActionUnavailableBehaviour.Disable);
|
||||
View.SetActionTarget(this.subject, null);
|
||||
Assert.False(cmd.CanExecute(null));
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ namespace StyletUnitTests
|
|||
[Test]
|
||||
public void EnablesIfTargetNullBehaviourIsEnableAndTargetIsNull()
|
||||
{
|
||||
var cmd = new CommandAction(this.subject, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Disable);
|
||||
var cmd = new CommandAction(this.subject, null, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Disable);
|
||||
View.SetActionTarget(this.subject, null);
|
||||
Assert.True(cmd.CanExecute(null));
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ namespace StyletUnitTests
|
|||
[Test]
|
||||
public void ThrowsIfActionNonExistentBehaviourIsThrowAndActionIsNonExistent()
|
||||
{
|
||||
var cmd = new CommandAction(this.subject, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
var cmd = new CommandAction(this.subject, null, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
Assert.DoesNotThrow(() => View.SetActionTarget(this.subject, new Target2()));
|
||||
Assert.Throws<ActionNotFoundException>(() => cmd.Execute(null));
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ namespace StyletUnitTests
|
|||
[Test]
|
||||
public void DisablesIfActionNonExistentBehaviourIsThrowAndActionIsNonExistent()
|
||||
{
|
||||
var cmd = new CommandAction(this.subject, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Disable);
|
||||
var cmd = new CommandAction(this.subject, null, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Disable);
|
||||
View.SetActionTarget(this.subject, new Target2());
|
||||
Assert.False(cmd.CanExecute(null));
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ namespace StyletUnitTests
|
|||
[Test]
|
||||
public void EnablesIfActionNonExistentBehaviourIsThrowAndActionIsNonExistent()
|
||||
{
|
||||
var cmd = new CommandAction(this.subject, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Enable);
|
||||
var cmd = new CommandAction(this.subject, null, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Enable);
|
||||
View.SetActionTarget(this.subject, new Target2());
|
||||
Assert.True(cmd.CanExecute(null));
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ namespace StyletUnitTests
|
|||
[Test]
|
||||
public void EnablesIfTargetAndActionExistAndNoGuardMethod()
|
||||
{
|
||||
var cmd = new CommandAction(this.subject, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
var cmd = new CommandAction(this.subject, null, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
Assert.True(cmd.CanExecute(null));
|
||||
}
|
||||
|
||||
|
@ -131,7 +131,7 @@ namespace StyletUnitTests
|
|||
public void EnablesIfTargetAndActionExistAndGuardMethodReturnsTrue()
|
||||
{
|
||||
this.target.CanDoSomethingWithGuard = true;
|
||||
var cmd = new CommandAction(this.subject, "DoSomethingWithGuard", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
var cmd = new CommandAction(this.subject, null, "DoSomethingWithGuard", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
Assert.True(cmd.CanExecute(null));
|
||||
}
|
||||
|
||||
|
@ -139,14 +139,14 @@ namespace StyletUnitTests
|
|||
public void DisablesIfTargetAndActionExistAndGuardMethodReturnsFalse()
|
||||
{
|
||||
this.target.CanDoSomethingWithGuard = false;
|
||||
var cmd = new CommandAction(this.subject, "DoSomethingWithGuard", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
var cmd = new CommandAction(this.subject, null, "DoSomethingWithGuard", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
Assert.False(cmd.CanExecute(null));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IgnoresGuardIfGuardDoesNotReturnBool()
|
||||
{
|
||||
var cmd = new CommandAction(this.subject, "DoSomethingWithBadGuard", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
var cmd = new CommandAction(this.subject, null, "DoSomethingWithBadGuard", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
Assert.True(cmd.CanExecute(true));
|
||||
}
|
||||
|
||||
|
@ -154,7 +154,7 @@ namespace StyletUnitTests
|
|||
public void ChangesEnabledStateWhenGuardChanges()
|
||||
{
|
||||
this.target.CanDoSomethingWithGuard = false;
|
||||
var cmd = new CommandAction(this.subject, "DoSomethingWithGuard", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
var cmd = new CommandAction(this.subject, null, "DoSomethingWithGuard", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
Assert.False(cmd.CanExecute(null));
|
||||
this.target.CanDoSomethingWithGuard = true;
|
||||
Assert.True(cmd.CanExecute(null));
|
||||
|
@ -164,7 +164,7 @@ namespace StyletUnitTests
|
|||
public void RaisesEventWhenGuardValueChanges()
|
||||
{
|
||||
this.target.CanDoSomethingWithGuard = false;
|
||||
var cmd = new CommandAction(this.subject, "DoSomethingWithGuard", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
var cmd = new CommandAction(this.subject, null, "DoSomethingWithGuard", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
bool eventRaised = false;
|
||||
cmd.CanExecuteChanged += (o, e) => eventRaised = true;
|
||||
this.target.CanDoSomethingWithGuard = true;
|
||||
|
@ -174,7 +174,7 @@ namespace StyletUnitTests
|
|||
[Test]
|
||||
public void RaisesEventWhenTargetChanges()
|
||||
{
|
||||
var cmd = new CommandAction(this.subject, "DoSomething", ActionUnavailableBehaviour.Disable, ActionUnavailableBehaviour.Disable);
|
||||
var cmd = new CommandAction(this.subject, null, "DoSomething", ActionUnavailableBehaviour.Disable, ActionUnavailableBehaviour.Disable);
|
||||
bool eventRaised = false;
|
||||
cmd.CanExecuteChanged += (o, e) => eventRaised = true;
|
||||
View.SetActionTarget(this.subject, null);
|
||||
|
@ -184,7 +184,7 @@ namespace StyletUnitTests
|
|||
[Test]
|
||||
public void ExecuteDoesNothingIfTargetIsNull()
|
||||
{
|
||||
var cmd = new CommandAction(this.subject, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
var cmd = new CommandAction(this.subject, null, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
View.SetActionTarget(this.subject, null);
|
||||
Assert.DoesNotThrow(() => cmd.Execute(null));
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ namespace StyletUnitTests
|
|||
[Test]
|
||||
public void ExecuteDoesNothingIfActionIsNull()
|
||||
{
|
||||
var cmd = new CommandAction(this.subject, "DoesNotExist", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
var cmd = new CommandAction(this.subject, null, "DoesNotExist", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
View.SetActionTarget(this.subject, null);
|
||||
Assert.DoesNotThrow(() => cmd.Execute(null));
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ namespace StyletUnitTests
|
|||
[Test]
|
||||
public void ExecuteCallsMethod()
|
||||
{
|
||||
var cmd = new CommandAction(this.subject, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
var cmd = new CommandAction(this.subject, null, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
cmd.Execute(null);
|
||||
Assert.True(this.target.DoSomethingCalled);
|
||||
}
|
||||
|
@ -208,7 +208,7 @@ namespace StyletUnitTests
|
|||
[Test]
|
||||
public void ExecutePassesArgumentIfGiven()
|
||||
{
|
||||
var cmd = new CommandAction(this.subject, "DoSomethingWithArgument", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
var cmd = new CommandAction(this.subject, null, "DoSomethingWithArgument", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
var arg = "hello";
|
||||
cmd.Execute(arg);
|
||||
Assert.AreEqual("hello", this.target.DoSomethingArgument);
|
||||
|
@ -217,13 +217,13 @@ namespace StyletUnitTests
|
|||
[Test]
|
||||
public void ThrowsIfMethodHasMoreThanOneParameter()
|
||||
{
|
||||
Assert.Throws<ActionSignatureInvalidException>(() => new CommandAction(this.subject, "DoSomethingWithManyArguments", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable));
|
||||
Assert.Throws<ActionSignatureInvalidException>(() => new CommandAction(this.subject, null, "DoSomethingWithManyArguments", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PropagatesActionException()
|
||||
{
|
||||
var cmd = new CommandAction(this.subject, "DoSomethingUnsuccessfully", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
var cmd = new CommandAction(this.subject, null, "DoSomethingUnsuccessfully", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
var e = Assert.Throws<InvalidOperationException>(() => cmd.Execute(null));
|
||||
Assert.AreEqual("woo", e.Message);
|
||||
}
|
||||
|
@ -231,7 +231,7 @@ namespace StyletUnitTests
|
|||
[Test]
|
||||
public void PropagatesGuardPropertException()
|
||||
{
|
||||
var cmd = new CommandAction(this.subject, "DoSomethingWithUnsuccessfulGuardMethod", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
var cmd = new CommandAction(this.subject, null, "DoSomethingWithUnsuccessfulGuardMethod", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
var e = Assert.Throws<InvalidOperationException>(() => cmd.CanExecute(null));
|
||||
Assert.AreEqual("foo", e.Message);
|
||||
}
|
||||
|
@ -240,7 +240,7 @@ namespace StyletUnitTests
|
|||
public void ControlIsEnabledIfTargetIsDefault()
|
||||
{
|
||||
View.SetActionTarget(this.subject, View.InitialActionTarget);
|
||||
var cmd = new CommandAction(this.subject, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
var cmd = new CommandAction(this.subject, null, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
Assert.True(cmd.CanExecute(null));
|
||||
}
|
||||
|
||||
|
@ -248,7 +248,7 @@ namespace StyletUnitTests
|
|||
public void ExecuteThrowsIfTargetIsDefault()
|
||||
{
|
||||
View.SetActionTarget(this.subject, View.InitialActionTarget);
|
||||
var cmd = new CommandAction(this.subject, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
var cmd = new CommandAction(this.subject, null, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
Assert.Throws<ActionNotSetException>(() => cmd.Execute(null));
|
||||
}
|
||||
|
||||
|
@ -258,7 +258,7 @@ namespace StyletUnitTests
|
|||
var view = new DependencyObject();
|
||||
var weakView = new WeakReference(view);
|
||||
View.SetActionTarget(view, this.target);
|
||||
var cmd = new CommandAction(view, "DoSomethingWithGuard", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
var cmd = new CommandAction(view, null, "DoSomethingWithGuard", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
|
||||
view = null;
|
||||
cmd = null;
|
||||
|
@ -272,7 +272,7 @@ namespace StyletUnitTests
|
|||
public void OperatesAfterCollection()
|
||||
{
|
||||
var view = new DependencyObject();
|
||||
var cmd = new CommandAction(view, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
var cmd = new CommandAction(view, null, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
|
||||
GC.Collect();
|
||||
|
||||
|
@ -281,5 +281,19 @@ namespace StyletUnitTests
|
|||
cmd.Execute(null);
|
||||
Assert.IsTrue(this.target.DoSomethingCalled);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UsesDataContextIfActionTargetNotAvailable()
|
||||
{
|
||||
var view = new DependencyObject();
|
||||
var backupView = new DependencyObject();
|
||||
var cmd = new CommandAction(backupView, null, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
|
||||
View.SetActionTarget(backupView, this.target);
|
||||
view.SetValue(FrameworkElement.DataContextProperty, this.target);
|
||||
|
||||
cmd.Execute(null);
|
||||
Assert.IsTrue(this.target.DoSomethingCalled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,26 +92,26 @@ namespace StyletUnitTests
|
|||
[Test]
|
||||
public void ThrowsIfNullTargetBehaviourIsDisable()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => new EventAction(this.subject, this.eventInfo.EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Disable, ActionUnavailableBehaviour.Enable));
|
||||
Assert.Throws<ArgumentException>(() => new EventAction(this.subject, null, this.eventInfo.EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Disable, ActionUnavailableBehaviour.Enable));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ThrowsIfNonExistentActionBehaviourIsDisable()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => new EventAction(this.subject, this.eventInfo.EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Disable));
|
||||
Assert.Throws<ArgumentException>(() => new EventAction(this.subject, null, this.eventInfo.EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Disable));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ThrowsIfTargetNullBehaviourIsThrowAndTargetBecomesNull()
|
||||
{
|
||||
var cmd = new EventAction(this.subject, this.eventInfo.EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Enable);
|
||||
var cmd = new EventAction(this.subject, null, this.eventInfo.EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Enable);
|
||||
Assert.Throws<ActionTargetNullException>(() => View.SetActionTarget(this.subject, null));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ThrowsWhenClickedIfActionNonExistentBehaviourIsThrowAndActionIsNonExistent()
|
||||
{
|
||||
var cmd = new EventAction(this.subject, this.eventInfo.EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Throw);
|
||||
var cmd = new EventAction(this.subject, null, this.eventInfo.EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Throw);
|
||||
Assert.DoesNotThrow(() => View.SetActionTarget(this.subject, new Target2()));
|
||||
var e = Assert.Throws<TargetInvocationException>(() => cmd.GetDelegate().DynamicInvoke(null, new RoutedEventArgs()));
|
||||
Assert.IsInstanceOf<ActionNotFoundException>(e.InnerException);
|
||||
|
@ -120,31 +120,31 @@ namespace StyletUnitTests
|
|||
[Test]
|
||||
public void ThrowsIfMethodHasTooManyArguments()
|
||||
{
|
||||
Assert.Throws<ActionSignatureInvalidException>(() => new EventAction(this.subject, this.eventInfo.EventHandlerType, "DoSomethingWithTooManyArguments", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable));
|
||||
Assert.Throws<ActionSignatureInvalidException>(() => new EventAction(this.subject, null, this.eventInfo.EventHandlerType, "DoSomethingWithTooManyArguments", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ThrowsIfMethodHasBadParameter()
|
||||
{
|
||||
Assert.Throws<ActionSignatureInvalidException>(() => new EventAction(this.subject, this.eventInfo.EventHandlerType, "DoSomethingWithBadArgument", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable));
|
||||
Assert.Throws<ActionSignatureInvalidException>(() => new EventAction(this.subject, null, this.eventInfo.EventHandlerType, "DoSomethingWithBadArgument", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ThrowsIfMethodHasBadEventArgsParameter()
|
||||
{
|
||||
Assert.Throws<ActionSignatureInvalidException>(() => new EventAction(this.subject, this.eventInfo.EventHandlerType, "DoSomethingWithSenderAndBadArgument", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable));
|
||||
Assert.Throws<ActionSignatureInvalidException>(() => new EventAction(this.subject, null, this.eventInfo.EventHandlerType, "DoSomethingWithSenderAndBadArgument", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ThrowsIfMethodHasTooManyParameters()
|
||||
{
|
||||
Assert.Throws<ActionSignatureInvalidException>(() => new EventAction(this.subject, this.eventInfo.EventHandlerType, "DoSomethingWithTooManyArguments", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable));
|
||||
Assert.Throws<ActionSignatureInvalidException>(() => new EventAction(this.subject, null, this.eventInfo.EventHandlerType, "DoSomethingWithTooManyArguments", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InvokingCommandDoesNothingIfTargetIsNull()
|
||||
{
|
||||
var cmd = new EventAction(this.subject, this.eventInfo.EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
var cmd = new EventAction(this.subject, null, this.eventInfo.EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
View.SetActionTarget(this.subject, null);
|
||||
cmd.GetDelegate().DynamicInvoke(null, null);
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ namespace StyletUnitTests
|
|||
[Test]
|
||||
public void InvokingCommandDoesNothingIfActionIsNonExistent()
|
||||
{
|
||||
var cmd = new EventAction(this.subject, this.eventInfo.EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
var cmd = new EventAction(this.subject, null, this.eventInfo.EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
View.SetActionTarget(this.subject, new Target2());
|
||||
cmd.GetDelegate().DynamicInvoke(null, null);
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ namespace StyletUnitTests
|
|||
[Test]
|
||||
public void InvokingCommandCallsMethod()
|
||||
{
|
||||
var cmd = new EventAction(this.subject, this.eventInfo.EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
var cmd = new EventAction(this.subject, null, this.eventInfo.EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
cmd.GetDelegate().DynamicInvoke(null, null);
|
||||
Assert.True(this.target.DoSomethingCalled);
|
||||
}
|
||||
|
@ -168,7 +168,7 @@ namespace StyletUnitTests
|
|||
[Test]
|
||||
public void InvokingCommandCallsMethodWithEventArgs()
|
||||
{
|
||||
var cmd = new EventAction(this.subject, this.eventInfo.EventHandlerType, "DoSomethingWithEventArgs", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
var cmd = new EventAction(this.subject, null, this.eventInfo.EventHandlerType, "DoSomethingWithEventArgs", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
var arg = new RoutedEventArgs();
|
||||
cmd.GetDelegate().DynamicInvoke(null, arg);
|
||||
Assert.AreEqual(arg, this.target.EventArgs);
|
||||
|
@ -177,7 +177,7 @@ namespace StyletUnitTests
|
|||
[Test]
|
||||
public void InvokingCommandCallsMethodWithSenderAndEventArgs()
|
||||
{
|
||||
var cmd = new EventAction(this.subject, this.eventInfo.EventHandlerType, "DoSomethingWithObjectAndEventArgs", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
var cmd = new EventAction(this.subject, null, this.eventInfo.EventHandlerType, "DoSomethingWithObjectAndEventArgs", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
var sender = new object();
|
||||
var arg = new RoutedEventArgs();
|
||||
cmd.GetDelegate().DynamicInvoke(sender, arg);
|
||||
|
@ -189,7 +189,7 @@ namespace StyletUnitTests
|
|||
[Test]
|
||||
public void InvokingCommandCallsMethodWithDependencyChangedEventArgs()
|
||||
{
|
||||
var cmd = new EventAction(this.subject, this.dependencyChangedEventInfo.EventHandlerType, "DoSomethingWithDependencyChangedEventArgs", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
var cmd = new EventAction(this.subject, null, this.dependencyChangedEventInfo.EventHandlerType, "DoSomethingWithDependencyChangedEventArgs", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
var arg = new DependencyPropertyChangedEventArgs();
|
||||
cmd.GetDelegate().DynamicInvoke(null, arg);
|
||||
Assert.AreEqual(arg, this.target.DependencyChangedEventArgs);
|
||||
|
@ -198,7 +198,7 @@ namespace StyletUnitTests
|
|||
[Test]
|
||||
public void InvokingCommandCallsMethodWithSenderAndDependencyChangedEventArgs()
|
||||
{
|
||||
var cmd = new EventAction(this.subject, this.dependencyChangedEventInfo.EventHandlerType, "DoSomethingWithObjectAndDependencyChangedEventArgs", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
var cmd = new EventAction(this.subject, null, this.dependencyChangedEventInfo.EventHandlerType, "DoSomethingWithObjectAndDependencyChangedEventArgs", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
var sender = new object();
|
||||
var arg = new DependencyPropertyChangedEventArgs();
|
||||
cmd.GetDelegate().DynamicInvoke(sender, arg);
|
||||
|
@ -210,14 +210,14 @@ namespace StyletUnitTests
|
|||
[Test]
|
||||
public void BadEventHandlerSignatureThrows()
|
||||
{
|
||||
var cmd = new EventAction(this.subject, typeof(Subject).GetEvent("BadEventHandler").EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
var cmd = new EventAction(this.subject, null, typeof(Subject).GetEvent("BadEventHandler").EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
Assert.Throws<ActionEventSignatureInvalidException>(() => cmd.GetDelegate());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PropagatesActionException()
|
||||
{
|
||||
var cmd = new EventAction(this.subject, this.eventInfo.EventHandlerType, "DoSomethingUnsuccessfully", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
var cmd = new EventAction(this.subject, null, this.eventInfo.EventHandlerType, "DoSomethingUnsuccessfully", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
|
||||
var e = Assert.Throws<TargetInvocationException>(() => cmd.GetDelegate().DynamicInvoke(null, null));
|
||||
Assert.IsInstanceOf<InvalidOperationException>(e.InnerException);
|
||||
Assert.AreEqual("foo", e.InnerException.Message);
|
||||
|
@ -227,7 +227,7 @@ namespace StyletUnitTests
|
|||
public void ExecuteThrowsIfActionTargetIsDefault()
|
||||
{
|
||||
View.SetActionTarget(this.subject, View.InitialActionTarget);
|
||||
var cmd = new EventAction(this.subject, this.eventInfo.EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
var cmd = new EventAction(this.subject, null, this.eventInfo.EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
var e = Assert.Throws<TargetInvocationException>(() => cmd.GetDelegate().DynamicInvoke(null, null));
|
||||
Assert.IsInstanceOf<ActionNotSetException>(e.InnerException);
|
||||
}
|
||||
|
@ -238,7 +238,7 @@ namespace StyletUnitTests
|
|||
var view = new DependencyObject();
|
||||
var weakView = new WeakReference(view);
|
||||
View.SetActionTarget(view, this.target);
|
||||
var cmd = new EventAction(view, this.eventInfo.EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
var cmd = new EventAction(view, null, this.eventInfo.EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
|
||||
cmd = null;
|
||||
view = null;
|
||||
|
@ -251,7 +251,7 @@ namespace StyletUnitTests
|
|||
public void OperatesAfterCollection()
|
||||
{
|
||||
var view = new DependencyObject();
|
||||
var cmd = new EventAction(view, this.eventInfo.EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
var cmd = new EventAction(view, null, this.eventInfo.EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
|
||||
GC.Collect();
|
||||
|
||||
|
@ -260,5 +260,19 @@ namespace StyletUnitTests
|
|||
cmd.GetDelegate().DynamicInvoke(null, null);
|
||||
Assert.IsTrue(this.target.DoSomethingCalled);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UsesBackupSubjectIfActionTargetNotAvailable()
|
||||
{
|
||||
var view = new DependencyObject();
|
||||
var backupView = new DependencyObject();
|
||||
var cmd = new CommandAction(view, backupView, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||
|
||||
View.SetActionTarget(backupView, this.target);
|
||||
view.SetValue(FrameworkElement.DataContextProperty, this.target);
|
||||
|
||||
cmd.Execute(null);
|
||||
Assert.IsTrue(this.target.DoSomethingCalled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue