Browse Source
Added a new `IsEnabledCore` property to `InputElement` which is overridden in `Button` and `MenuItem` to override the `IsEffectivelyEnabled` state with the enabled state of the command. Also add data validation of the `Command` property to `MenuItem` to make it behave the same as `Button` when `Command` is bound to a non-existent property. Fixes #2501pull/2529/head
6 changed files with 294 additions and 75 deletions
@ -0,0 +1,101 @@ |
|||||
|
// Copyright (c) The Avalonia Project. All rights reserved.
|
||||
|
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
||||
|
|
||||
|
using Avalonia.Controls; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Avalonia.Input.UnitTests |
||||
|
{ |
||||
|
public class InputElement_Enabled |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void IsEffectivelyEnabled_Follows_IsEnabled() |
||||
|
{ |
||||
|
var target = new Decorator(); |
||||
|
|
||||
|
Assert.True(target.IsEnabled); |
||||
|
Assert.True(target.IsEffectivelyEnabled); |
||||
|
|
||||
|
target.IsEnabled = false; |
||||
|
|
||||
|
Assert.False(target.IsEnabled); |
||||
|
Assert.False(target.IsEffectivelyEnabled); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void IsEffectivelyEnabled_Follows_Ancestor_IsEnabled() |
||||
|
{ |
||||
|
Decorator child; |
||||
|
Decorator grandchild; |
||||
|
var target = new Decorator |
||||
|
{ |
||||
|
Child = child = new Decorator |
||||
|
{ |
||||
|
Child = grandchild = new Decorator(), |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
Assert.True(target.IsEnabled); |
||||
|
Assert.True(target.IsEffectivelyEnabled); |
||||
|
Assert.True(child.IsEnabled); |
||||
|
Assert.True(child.IsEffectivelyEnabled); |
||||
|
Assert.True(grandchild.IsEnabled); |
||||
|
Assert.True(grandchild.IsEffectivelyEnabled); |
||||
|
|
||||
|
target.IsEnabled = false; |
||||
|
|
||||
|
Assert.False(target.IsEnabled); |
||||
|
Assert.False(target.IsEffectivelyEnabled); |
||||
|
Assert.True(child.IsEnabled); |
||||
|
Assert.False(child.IsEffectivelyEnabled); |
||||
|
Assert.True(grandchild.IsEnabled); |
||||
|
Assert.False(grandchild.IsEffectivelyEnabled); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Disabled_Pseudoclass_Follows_IsEffectivelyEnabled() |
||||
|
{ |
||||
|
Decorator child; |
||||
|
var target = new Decorator |
||||
|
{ |
||||
|
Child = child = new Decorator() |
||||
|
}; |
||||
|
|
||||
|
Assert.DoesNotContain(":disabled", child.Classes); |
||||
|
|
||||
|
target.IsEnabled = false; |
||||
|
|
||||
|
Assert.Contains(":disabled", child.Classes); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void IsEffectivelyEnabled_Respects_IsEnabledCore() |
||||
|
{ |
||||
|
Decorator child; |
||||
|
var target = new TestControl |
||||
|
{ |
||||
|
Child = child = new Decorator() |
||||
|
}; |
||||
|
|
||||
|
target.ShouldEnable = false; |
||||
|
|
||||
|
Assert.True(target.IsEnabled); |
||||
|
Assert.False(target.IsEffectivelyEnabled); |
||||
|
Assert.True(child.IsEnabled); |
||||
|
Assert.False(child.IsEffectivelyEnabled); |
||||
|
} |
||||
|
|
||||
|
private class TestControl : Decorator |
||||
|
{ |
||||
|
private bool _shouldEnable; |
||||
|
|
||||
|
public bool ShouldEnable |
||||
|
{ |
||||
|
get => _shouldEnable; |
||||
|
set { _shouldEnable = value; UpdateIsEffectivelyEnabled(); } |
||||
|
} |
||||
|
|
||||
|
protected override bool IsEnabledCore => IsEnabled && _shouldEnable; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue