Report guards as best we can if the target does not implement INPC

Fixes #214
This commit is contained in:
Antony Male 2021-02-15 08:53:39 +00:00
parent 3101fcd99a
commit c82cdb9321
2 changed files with 35 additions and 18 deletions

View File

@ -65,16 +65,11 @@ namespace Stylet.Xaml
/// <param name="newTarget">New target</param> /// <param name="newTarget">New target</param>
protected internal override void OnTargetChanged(object oldTarget, object newTarget) protected internal override void OnTargetChanged(object oldTarget, object newTarget)
{ {
var oldInpc = oldTarget as INotifyPropertyChanged; if (oldTarget is INotifyPropertyChanged oldInpc)
if (oldInpc != null)
PropertyChangedEventManager.RemoveHandler(oldInpc, this.PropertyChangedHandler, this.GuardName); PropertyChangedEventManager.RemoveHandler(oldInpc, this.PropertyChangedHandler, this.GuardName);
this.guardPropertyGetter = null; this.guardPropertyGetter = null;
var guardPropertyInfo = newTarget?.GetType().GetProperty(this.GuardName);
var inpc = newTarget as INotifyPropertyChanged;
if (inpc != null)
{
var guardPropertyInfo = newTarget.GetType().GetProperty(this.GuardName);
if (guardPropertyInfo != null) if (guardPropertyInfo != null)
{ {
if (guardPropertyInfo.PropertyType == typeof(bool)) if (guardPropertyInfo.PropertyType == typeof(bool))
@ -90,7 +85,11 @@ namespace Stylet.Xaml
} }
if (this.guardPropertyGetter != null) if (this.guardPropertyGetter != null)
{
if (newTarget is INotifyPropertyChanged inpc)
PropertyChangedEventManager.AddHandler(inpc, this.PropertyChangedHandler, this.GuardName); PropertyChangedEventManager.AddHandler(inpc, this.PropertyChangedHandler, this.GuardName);
else
logger.Warn("Found guard property {0} for action {1} on target {2}, but the target doesn't implement INotifyPropertyChanged, so changes won't be observed", this.GuardName, this.MethodName, newTarget);
} }
this.UpdateCanExecute(); this.UpdateCanExecute();

View File

@ -62,6 +62,12 @@ namespace StyletUnitTests
{ {
} }
private class TargetWithoutInpc
{
public bool CanDoSomething => false;
public void DoSomething() { }
}
private DependencyObject subject; private DependencyObject subject;
private Target target; private Target target;
@ -171,6 +177,18 @@ namespace StyletUnitTests
Assert.True(eventRaised); Assert.True(eventRaised);
} }
[Test]
public void FetchesGuardPropertyWhenTargetDoesNotImplementInpc()
{
var target = new TargetWithoutInpc();
var cmd = new CommandAction(this.subject, null, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
bool eventRaised = false;
cmd.CanExecuteChanged += (o, e) => eventRaised = true;
View.SetActionTarget(this.subject, target);
Assert.True(eventRaised);
Assert.False(cmd.CanExecute(null));
}
[Test] [Test]
public void RaisesEventWhenTargetChanges() public void RaisesEventWhenTargetChanges()
{ {