diff --git a/src/Avalonia.Controls/MenuItem.cs b/src/Avalonia.Controls/MenuItem.cs index 96f6fb59b0..cec653e045 100644 --- a/src/Avalonia.Controls/MenuItem.cs +++ b/src/Avalonia.Controls/MenuItem.cs @@ -72,10 +72,7 @@ namespace Avalonia.Controls /// The default value for the property. /// private static readonly ITemplate DefaultPanel = - new FuncTemplate(() => new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Cycle, - }); + new FuncTemplate(() => new StackPanel()); /// /// The timer used to display submenus. diff --git a/src/Avalonia.Controls/Presenters/ItemsPresenter.cs b/src/Avalonia.Controls/Presenters/ItemsPresenter.cs index f8d62a1cbf..500c7aa187 100644 --- a/src/Avalonia.Controls/Presenters/ItemsPresenter.cs +++ b/src/Avalonia.Controls/Presenters/ItemsPresenter.cs @@ -143,13 +143,6 @@ namespace Avalonia.Controls.Presenters Virtualizer = ItemVirtualizer.Create(this); ((ILogicalScrollable)this).InvalidateScroll?.Invoke(); - if (!Panel.IsSet(KeyboardNavigation.DirectionalNavigationProperty)) - { - KeyboardNavigation.SetDirectionalNavigation( - (InputElement)Panel, - KeyboardNavigationMode.Contained); - } - KeyboardNavigation.SetTabNavigation( (InputElement)Panel, KeyboardNavigation.GetTabNavigation(this)); @@ -175,4 +168,4 @@ namespace Avalonia.Controls.Presenters ((ILogicalScrollable)this).InvalidateScroll?.Invoke(); } } -} \ No newline at end of file +} diff --git a/src/Avalonia.Controls/TreeViewItem.cs b/src/Avalonia.Controls/TreeViewItem.cs index bed27ef033..8af3333dd4 100644 --- a/src/Avalonia.Controls/TreeViewItem.cs +++ b/src/Avalonia.Controls/TreeViewItem.cs @@ -32,10 +32,7 @@ namespace Avalonia.Controls ListBoxItem.IsSelectedProperty.AddOwner(); private static readonly ITemplate DefaultPanel = - new FuncTemplate(() => new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, - }); + new FuncTemplate(() => new StackPanel()); private TreeView _treeView; private bool _isExpanded; diff --git a/src/Avalonia.Input/KeyboardNavigation.cs b/src/Avalonia.Input/KeyboardNavigation.cs index cbd9a74f4c..0277876e24 100644 --- a/src/Avalonia.Input/KeyboardNavigation.cs +++ b/src/Avalonia.Input/KeyboardNavigation.cs @@ -8,19 +8,6 @@ namespace Avalonia.Input /// public static class KeyboardNavigation { - /// - /// Defines the DirectionalNavigation attached property. - /// - /// - /// The DirectionalNavigation attached property defines how pressing arrow keys causes - /// focus to be navigated between the children of the container. - /// - public static readonly AttachedProperty DirectionalNavigationProperty = - AvaloniaProperty.RegisterAttached( - "DirectionalNavigation", - typeof(KeyboardNavigation), - KeyboardNavigationMode.None); - /// /// Defines the TabNavigation attached property. /// @@ -46,26 +33,6 @@ namespace Avalonia.Input "TabOnceActiveElement", typeof(KeyboardNavigation)); - /// - /// Gets the for a container. - /// - /// The container. - /// The for the container. - public static KeyboardNavigationMode GetDirectionalNavigation(InputElement element) - { - return element.GetValue(DirectionalNavigationProperty); - } - - /// - /// Sets the for a container. - /// - /// The container. - /// The for the container. - public static void SetDirectionalNavigation(InputElement element, KeyboardNavigationMode value) - { - element.SetValue(DirectionalNavigationProperty, value); - } - /// /// Gets the for a container. /// diff --git a/src/Avalonia.Input/KeyboardNavigationHandler.cs b/src/Avalonia.Input/KeyboardNavigationHandler.cs index bf2b61d08b..bc3098a7fb 100644 --- a/src/Avalonia.Input/KeyboardNavigationHandler.cs +++ b/src/Avalonia.Input/KeyboardNavigationHandler.cs @@ -85,7 +85,7 @@ namespace Avalonia.Input } else { - return DirectionalNavigation.GetNext(element, direction); + throw new NotSupportedException(); } } @@ -122,47 +122,12 @@ namespace Avalonia.Input { var current = FocusManager.Instance.Current; - if (current != null) + if (current != null && e.Key == Key.Tab) { - NavigationDirection? direction = null; - - switch (e.Key) - { - case Key.Tab: - direction = (e.Modifiers & InputModifiers.Shift) == 0 ? - NavigationDirection.Next : NavigationDirection.Previous; - break; - case Key.Up: - direction = NavigationDirection.Up; - break; - case Key.Down: - direction = NavigationDirection.Down; - break; - case Key.Left: - direction = NavigationDirection.Left; - break; - case Key.Right: - direction = NavigationDirection.Right; - break; - case Key.PageUp: - direction = NavigationDirection.PageUp; - break; - case Key.PageDown: - direction = NavigationDirection.PageDown; - break; - case Key.Home: - direction = NavigationDirection.First; - break; - case Key.End: - direction = NavigationDirection.Last; - break; - } - - if (direction.HasValue) - { - Move(current, direction.Value, e.Modifiers); - e.Handled = true; - } + var direction = (e.Modifiers & InputModifiers.Shift) == 0 ? + NavigationDirection.Next : NavigationDirection.Previous; + Move(current, direction, e.Modifiers); + e.Handled = true; } } } diff --git a/src/Avalonia.Input/Navigation/DirectionalNavigation.cs b/src/Avalonia.Input/Navigation/DirectionalNavigation.cs deleted file mode 100644 index 75cb3a39e8..0000000000 --- a/src/Avalonia.Input/Navigation/DirectionalNavigation.cs +++ /dev/null @@ -1,242 +0,0 @@ -// 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 System; -using System.Collections.Generic; -using System.Linq; -using Avalonia.VisualTree; - -namespace Avalonia.Input.Navigation -{ - /// - /// The implementation for default directional navigation. - /// - public static class DirectionalNavigation - { - /// - /// Gets the next control in the specified navigation direction. - /// - /// The element. - /// The navigation direction. - /// - /// The next element in the specified direction, or null if - /// was the last in the requested direction. - /// - public static IInputElement GetNext( - IInputElement element, - NavigationDirection direction) - { - Contract.Requires(element != null); - Contract.Requires( - direction != NavigationDirection.Next && - direction != NavigationDirection.Previous); - - var container = element.GetVisualParent(); - - if (container != null) - { - var mode = KeyboardNavigation.GetDirectionalNavigation((InputElement)container); - - switch (mode) - { - case KeyboardNavigationMode.Continue: - return GetNextInContainer(element, container, direction) ?? - GetFirstInNextContainer(element, element, direction); - case KeyboardNavigationMode.Cycle: - return GetNextInContainer(element, container, direction) ?? - GetFocusableDescendant(container, direction); - case KeyboardNavigationMode.Contained: - return GetNextInContainer(element, container, direction); - default: - return null; - } - } - else - { - return GetFocusableDescendants(element).FirstOrDefault(); - } - } - - /// - /// Returns a value indicting whether the specified direction is forward. - /// - /// The direction. - /// True if the direction is forward. - private static bool IsForward(NavigationDirection direction) - { - return direction == NavigationDirection.Next || - direction == NavigationDirection.Last || - direction == NavigationDirection.Right || - direction == NavigationDirection.Down; - } - - /// - /// Gets the first or last focusable descendant of the specified element. - /// - /// The element. - /// The direction to search. - /// The element or null if not found.## - private static IInputElement GetFocusableDescendant(IInputElement container, NavigationDirection direction) - { - return IsForward(direction) ? - GetFocusableDescendants(container).FirstOrDefault() : - GetFocusableDescendants(container).LastOrDefault(); - } - - /// - /// Gets the focusable descendants of the specified element. - /// - /// The element. - /// The element's focusable descendants. - private static IEnumerable GetFocusableDescendants(IInputElement element) - { - var children = element.GetVisualChildren().OfType(); - - foreach (var child in children) - { - if (child.CanFocus()) - { - yield return child; - } - - if (child.CanFocusDescendants()) - { - foreach (var descendant in GetFocusableDescendants(child)) - { - yield return descendant; - } - } - } - } - - /// - /// Gets the next item that should be focused in the specified container. - /// - /// The starting element/ - /// The container. - /// The direction. - /// The next element, or null if the element is the last. - private static IInputElement GetNextInContainer( - IInputElement element, - IInputElement container, - NavigationDirection direction) - { - if (direction == NavigationDirection.Down) - { - var descendant = GetFocusableDescendants(element).FirstOrDefault(); - - if (descendant != null) - { - return descendant; - } - } - - if (container != null) - { - var navigable = container as INavigableContainer; - - if (navigable != null) - { - while (element != null) - { - element = navigable.GetControl(direction, element); - - if (element != null && element.CanFocus()) - { - break; - } - } - } - else - { - // TODO: Do a spatial search here if the container doesn't implement - // INavigableContainer. - element = null; - } - - if (element != null && direction == NavigationDirection.Up) - { - var descendant = GetFocusableDescendants(element).LastOrDefault(); - - if (descendant != null) - { - return descendant; - } - } - - return element; - } - - return null; - } - - /// - /// Gets the first item that should be focused in the next container. - /// - /// The element being navigated away from. - /// The container. - /// The direction of the search. - /// The first element, or null if there are no more elements. - private static IInputElement GetFirstInNextContainer( - IInputElement element, - IInputElement container, - NavigationDirection direction) - { - var parent = container.GetVisualParent(); - var isForward = IsForward(direction); - IInputElement next = null; - - if (parent != null) - { - if (!isForward && parent.CanFocus()) - { - return parent; - } - - var siblings = parent.GetVisualChildren() - .OfType() - .Where(FocusExtensions.CanFocusDescendants); - var sibling = isForward ? - siblings.SkipWhile(x => x != container).Skip(1).FirstOrDefault() : - siblings.TakeWhile(x => x != container).LastOrDefault(); - - if (sibling != null) - { - if (sibling is ICustomKeyboardNavigation custom) - { - var (handled, customNext) = custom.GetNext(element, direction); - - if (handled) - { - return customNext; - } - } - - if (sibling.CanFocus()) - { - next = sibling; - } - else - { - next = isForward ? - GetFocusableDescendants(sibling).FirstOrDefault() : - GetFocusableDescendants(sibling).LastOrDefault(); - } - } - - if (next == null) - { - next = GetFirstInNextContainer(element, parent, direction); - } - } - else - { - next = isForward ? - GetFocusableDescendants(container).FirstOrDefault() : - GetFocusableDescendants(container).LastOrDefault(); - } - - return next; - } - } -} diff --git a/tests/Avalonia.Input.UnitTests/KeyboardNavigationTests_Arrows.cs b/tests/Avalonia.Input.UnitTests/KeyboardNavigationTests_Arrows.cs deleted file mode 100644 index b81b724e2a..0000000000 --- a/tests/Avalonia.Input.UnitTests/KeyboardNavigationTests_Arrows.cs +++ /dev/null @@ -1,799 +0,0 @@ -// 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 KeyboardNavigationTests_Arrows - { - [Fact] - public void Down_Continue_Returns_Down_Control_In_Container() - { - Button current; - Button next; - - var top = new StackPanel - { - Children = - { - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, - Children = - { - new Button { Name = "Button1" }, - (current = new Button { Name = "Button2" }), - (next = new Button { Name = "Button3" }), - } - }, - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, - Children = - { - new Button { Name = "Button4" }, - new Button { Name = "Button5" }, - new Button { Name = "Button6" }, - } - }, - } - }; - - var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Down); - - Assert.Equal(next, result); - } - - [Fact] - public void Down_Continue_Returns_First_Control_In_Down_Sibling_Container() - { - Button current; - Button next; - - var top = new StackPanel - { - Children = - { - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, - Children = - { - new Button { Name = "Button1" }, - new Button { Name = "Button2" }, - (current = new Button { Name = "Button3" }), - } - }, - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, - Children = - { - (next = new Button { Name = "Button4" }), - new Button { Name = "Button5" }, - new Button { Name = "Button6" }, - } - }, - } - }; - - var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Down); - - Assert.Equal(next, result); - } - - [Fact] - public void Down_Continue_Returns_Down_Sibling() - { - Button current; - Button next; - - var top = new StackPanel - { - Children = - { - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, - Children = - { - new Button { Name = "Button1" }, - new Button { Name = "Button2" }, - (current = new Button { Name = "Button3" }), - } - }, - (next = new Button { Name = "Button4" }), - } - }; - - var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Down); - - Assert.Equal(next, result); - } - - [Fact] - public void Down_Continue_Returns_First_Control_In_Down_Uncle_Container() - { - Button current; - Button next; - - var top = new StackPanel - { - Children = - { - new StackPanel - { - Children = - { - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, - Children = - { - new Button { Name = "Button1" }, - new Button { Name = "Button2" }, - (current = new Button { Name = "Button3" }), - } - }, - }, - }, - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, - Children = - { - (next = new Button { Name = "Button4" }), - new Button { Name = "Button5" }, - new Button { Name = "Button6" }, - } - }, - } - }; - - var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Down); - - Assert.Equal(next, result); - } - - [Fact] - public void Down_Continue_Returns_Child_Of_Top_Level() - { - Button next; - - var top = new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, - Children = - { - (next = new Button { Name = "Button1" }), - } - }; - - var result = KeyboardNavigationHandler.GetNext(top, NavigationDirection.Down); - - Assert.Equal(next, result); - } - - [Fact] - public void Down_Continue_Wraps() - { - Button current; - Button next; - - var top = new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, - Children = - { - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, - Children = - { - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, - Children = - { - (next = new Button { Name = "Button1" }), - new Button { Name = "Button2" }, - new Button { Name = "Button3" }, - } - }, - }, - }, - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, - Children = - { - new Button { Name = "Button4" }, - new Button { Name = "Button5" }, - (current = new Button { Name = "Button6" }), - } - }, - } - }; - - var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Down); - - Assert.Equal(next, result); - } - - [Fact] - public void Down_Cycle_Returns_Down_Control_In_Container() - { - Button current; - Button next; - - var top = new StackPanel - { - Children = - { - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Cycle, - Children = - { - new Button { Name = "Button1" }, - (current = new Button { Name = "Button2" }), - (next = new Button { Name = "Button3" }), - } - }, - new StackPanel - { - Children = - { - new Button { Name = "Button4" }, - new Button { Name = "Button5" }, - new Button { Name = "Button6" }, - } - }, - } - }; - - var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Down); - - Assert.Equal(next, result); - } - - [Fact] - public void Down_Cycle_Wraps_To_First() - { - Button current; - Button next; - - var top = new StackPanel - { - Children = - { - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Cycle, - Children = - { - (next = new Button { Name = "Button1" }), - new Button { Name = "Button2" }, - (current = new Button { Name = "Button3" }), - } - }, - new StackPanel - { - Children = - { - new Button { Name = "Button4" }, - new Button { Name = "Button5" }, - new Button { Name = "Button6" }, - } - }, - } - }; - - var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Down); - - Assert.Equal(next, result); - } - - [Fact] - public void Down_Contained_Returns_Down_Control_In_Container() - { - Button current; - Button next; - - var top = new StackPanel - { - Children = - { - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Contained, - Children = - { - new Button { Name = "Button1" }, - (current = new Button { Name = "Button2" }), - (next = new Button { Name = "Button3" }), - } - }, - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Contained, - Children = - { - new Button { Name = "Button4" }, - new Button { Name = "Button5" }, - new Button { Name = "Button6" }, - } - }, - } - }; - - var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Down); - - Assert.Equal(next, result); - } - - [Fact] - public void Down_Contained_Stops_At_End() - { - Button current; - - var top = new StackPanel - { - Children = - { - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Contained, - Children = - { - new Button { Name = "Button1" }, - new Button { Name = "Button2" }, - (current = new Button { Name = "Button3" }), - } - }, - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Contained, - Children = - { - new Button { Name = "Button4" }, - new Button { Name = "Button5" }, - new Button { Name = "Button6" }, - } - }, - } - }; - - var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Down); - - Assert.Null(result); - } - - [Fact] - public void Down_None_Does_Nothing() - { - Button current; - - var top = new StackPanel - { - Children = - { - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.None, - Children = - { - new Button { Name = "Button1" }, - (current = new Button { Name = "Button2" }), - new Button { Name = "Button3" }, - } - }, - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Contained, - Children = - { - new Button { Name = "Button4" }, - new Button { Name = "Button5" }, - new Button { Name = "Button6" }, - } - }, - } - }; - - var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Down); - - Assert.Null(result); - } - - [Fact] - public void Up_Continue_Returns_Up_Control_In_Container() - { - Button current; - Button next; - - var top = new StackPanel - { - Children = - { - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, - Children = - { - new Button { Name = "Button1" }, - (next = new Button { Name = "Button2" }), - (current = new Button { Name = "Button3" }), - } - }, - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Contained, - Children = - { - new Button { Name = "Button4" }, - new Button { Name = "Button5" }, - new Button { Name = "Button6" }, - } - }, - } - }; - - var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Up); - - Assert.Equal(next, result); - } - - [Fact] - public void Up_Continue_Returns_Last_Control_In_Up_Sibling_Container() - { - Button current; - Button next; - - var top = new StackPanel - { - Children = - { - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, - Children = - { - new Button { Name = "Button1" }, - new Button { Name = "Button2" }, - (next = new Button { Name = "Button3" }), - } - }, - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, - Children = - { - (current = new Button { Name = "Button4" }), - new Button { Name = "Button5" }, - new Button { Name = "Button6" }, - } - }, - } - }; - - var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Up); - - Assert.Equal(next, result); - } - - [Fact] - public void Up_Continue_Returns_Last_Child_Of_Sibling() - { - Button current; - Button next; - - var top = new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, - Children = - { - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, - Children = - { - new Button { Name = "Button1" }, - new Button { Name = "Button2" }, - (next = new Button { Name = "Button3" }), - } - }, - (current = new Button { Name = "Button4" }), - } - }; - - var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Up); - - Assert.Equal(next, result); - } - - [Fact] - public void Up_Continue_Returns_Last_Control_In_Up_Nephew_Container() - { - Button current; - Button next; - - var top = new StackPanel - { - Children = - { - new StackPanel - { - Children = - { - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, - Children = - { - new Button { Name = "Button1" }, - new Button { Name = "Button2" }, - (next = new Button { Name = "Button3" }), - } - }, - }, - }, - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, - Children = - { - (current = new Button { Name = "Button4" }), - new Button { Name = "Button5" }, - new Button { Name = "Button6" }, - } - }, - } - }; - - var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Up); - - Assert.Equal(next, result); - } - - [Fact] - public void Up_Continue_Wraps() - { - Button current; - Button next; - - var top = new StackPanel - { - Children = - { - new StackPanel - { - Children = - { - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, - Children = - { - (current = new Button { Name = "Button1" }), - new Button { Name = "Button2" }, - new Button { Name = "Button3" }, - } - }, - }, - }, - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, - Children = - { - new Button { Name = "Button4" }, - new Button { Name = "Button5" }, - (next = new Button { Name = "Button6" }), - } - }, - } - }; - - var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Up); - - Assert.Equal(next, result); - } - - [Fact] - public void Up_Continue_Returns_Parent() - { - Button current; - - var top = new Decorator - { - Focusable = true, - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, - Child = current = new Button - { - Name = "Button", - } - }; - - var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Up); - - Assert.Equal(top, result); - } - - [Fact] - public void Up_Cycle_Returns_Up_Control_In_Container() - { - Button current; - Button next; - - var top = new StackPanel - { - Children = - { - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Cycle, - Children = - { - (next = new Button { Name = "Button1" }), - (current = new Button { Name = "Button2" }), - new Button { Name = "Button3" }, - } - }, - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Cycle, - Children = - { - new Button { Name = "Button4" }, - new Button { Name = "Button5" }, - new Button { Name = "Button6" }, - } - }, - } - }; - - var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Up); - - Assert.Equal(next, result); - } - - [Fact] - public void Up_Cycle_Wraps_To_Last() - { - Button current; - Button next; - - var top = new StackPanel - { - Children = - { - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Cycle, - Children = - { - (current = new Button { Name = "Button1" }), - new Button { Name = "Button2" }, - (next = new Button { Name = "Button3" }), - } - }, - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Cycle, - Children = - { - new Button { Name = "Button4" }, - new Button { Name = "Button5" }, - new Button { Name = "Button6" }, - } - }, - } - }; - - var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Up); - - Assert.Equal(next, result); - } - - [Fact] - public void Up_Contained_Returns_Up_Control_In_Container() - { - Button current; - Button next; - - var top = new StackPanel - { - Children = - { - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Contained, - Children = - { - (next = new Button { Name = "Button1" }), - (current = new Button { Name = "Button2" }), - new Button { Name = "Button3" }, - } - }, - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Contained, - Children = - { - new Button { Name = "Button4" }, - new Button { Name = "Button5" }, - new Button { Name = "Button6" }, - } - }, - } - }; - - var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Up); - - Assert.Equal(next, result); - } - - [Fact] - public void Up_Contained_Stops_At_Beginning() - { - Button current; - - var top = new StackPanel - { - Children = - { - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Contained, - Children = - { - (current = new Button { Name = "Button1" }), - new Button { Name = "Button2" }, - new Button { Name = "Button3" }, - } - }, - new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Contained, - Children = - { - new Button { Name = "Button4" }, - new Button { Name = "Button5" }, - new Button { Name = "Button6" }, - } - }, - } - }; - - var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Up); - - Assert.Null(result); - } - - [Fact] - public void Up_Contained_Doesnt_Return_Child_Control() - { - Decorator current; - - var top = new StackPanel - { - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Contained, - Children = - { - (current = new Decorator - { - Focusable = true, - Child = new Button(), - }) - } - }; - - var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Up); - - Assert.Null(result); - } - } -} diff --git a/tests/Avalonia.Input.UnitTests/KeyboardNavigationTests_Custom.cs b/tests/Avalonia.Input.UnitTests/KeyboardNavigationTests_Custom.cs index a090dcd18d..ab0f5e2155 100644 --- a/tests/Avalonia.Input.UnitTests/KeyboardNavigationTests_Custom.cs +++ b/tests/Avalonia.Input.UnitTests/KeyboardNavigationTests_Custom.cs @@ -140,37 +140,6 @@ namespace Avalonia.Input.UnitTests Assert.Same(next, result); } - [Fact] - public void Right_Should_Custom_Navigate_From_Outside() - { - Button current; - Button next; - var target = new CustomNavigatingStackPanel - { - Children = - { - new Button { Content = "Button 1" }, - new Button { Content = "Button 2" }, - (next = new Button { Content = "Button 3" }), - }, - NextControl = next, - }; - - var root = new StackPanel - { - Children = - { - (current = new Button { Content = "Outside" }), - target, - }, - [KeyboardNavigation.DirectionalNavigationProperty] = KeyboardNavigationMode.Continue, - }; - - var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Right); - - Assert.Same(next, result); - } - [Fact] public void Tab_Should_Navigate_Outside_When_Null_Returned_As_Next() {