Browse Source

Disabled controls should lose focus and don't accept keyboard events

Daniil Pavliuchyk 2 years ago
parent
commit
80e1e1eb4c

+ 18 - 0
src/Avalonia.Base/Input/InputElement.cs

@@ -199,6 +199,7 @@ namespace Avalonia.Input
         private bool _isFocusVisible;
         private bool _isFocusVisible;
         private bool _isPointerOver;
         private bool _isPointerOver;
         private GestureRecognizerCollection? _gestureRecognizers;
         private GestureRecognizerCollection? _gestureRecognizers;
+        private bool _restoreFocus;
 
 
         /// <summary>
         /// <summary>
         /// Initializes static members of the <see cref="InputElement"/> class.
         /// Initializes static members of the <see cref="InputElement"/> class.
@@ -442,6 +443,23 @@ namespace Avalonia.Input
             {
             {
                 SetAndRaise(IsEffectivelyEnabledProperty, ref _isEffectivelyEnabled, value);
                 SetAndRaise(IsEffectivelyEnabledProperty, ref _isEffectivelyEnabled, value);
                 PseudoClasses.Set(":disabled", !value);
                 PseudoClasses.Set(":disabled", !value);
+
+                if (!IsEffectivelyEnabled)
+                {
+                    if (FocusManager.Instance?.Current == this)
+                    {
+                        _restoreFocus = true;
+                        FocusManager.Instance?.Focus(null);
+                    }
+                    else
+                    {
+                        _restoreFocus = false;
+                    }
+                }
+                else if (IsEffectivelyEnabled && _restoreFocus)
+                {
+                    FocusManager.Instance?.Focus(this);
+                }
             }
             }
         }
         }
 
 

+ 22 - 0
tests/Avalonia.Controls.UnitTests/TextBoxTests.cs

@@ -59,6 +59,28 @@ namespace Avalonia.Controls.UnitTests
             }
             }
         }
         }
 
 
+        [Fact]
+        public void TextBox_Should_Lose_Focus_When_Disabled()
+        {
+            using (UnitTestApplication.Start(FocusServices))
+            {
+                var target = new TextBox
+                {
+                    Template = CreateTemplate()
+                };
+
+                target.ApplyTemplate();
+
+                var root = new TestRoot() { Child = target };
+
+                target.Focus();
+                Assert.True(target.IsFocused);
+                target.IsEnabled = false;
+                Assert.False(target.IsFocused);
+                Assert.False(target.IsEnabled);
+            }
+        }
+
         [Fact]
         [Fact]
         public void Opening_Context_Flyout_Does_not_Lose_Selection()
         public void Opening_Context_Flyout_Does_not_Lose_Selection()
         {
         {