diff --git a/Perspex.Input/Navigation/DirectionalNavigation.cs b/Perspex.Input/Navigation/DirectionalNavigation.cs index 2248a09ee3..43e4c76d03 100644 --- a/Perspex.Input/Navigation/DirectionalNavigation.cs +++ b/Perspex.Input/Navigation/DirectionalNavigation.cs @@ -140,8 +140,6 @@ namespace Perspex.Input.Navigation { var navigable = container as INavigableContainer; - // TODO: Do a spatial search here if the container doesn't implement - // INavigableContainer. if (navigable != null) { while (element != null) @@ -154,6 +152,12 @@ namespace Perspex.Input.Navigation } } } + else + { + // TODO: Do a spatial search here if the container doesn't implement + // INavigableContainer. + element = null; + } if (element != null && direction == FocusNavigationDirection.Up) { @@ -187,6 +191,11 @@ namespace Perspex.Input.Navigation if (parent != null) { + if (!isForward && parent.CanFocus()) + { + return parent; + } + var siblings = parent.GetVisualChildren() .OfType() .Where(FocusExtensions.CanFocusDescendents); diff --git a/Perspex.Input/Navigation/TabNavigation.cs b/Perspex.Input/Navigation/TabNavigation.cs index 9bb77bbfc8..717c0245ac 100644 --- a/Perspex.Input/Navigation/TabNavigation.cs +++ b/Perspex.Input/Navigation/TabNavigation.cs @@ -161,6 +161,12 @@ namespace Perspex.Input.Navigation } } } + else + { + // TODO: Do a spatial search here if the container doesn't implement + // INavigableContainer. + element = null; + } if (element != null && direction == FocusNavigationDirection.Previous) { @@ -193,6 +199,11 @@ namespace Perspex.Input.Navigation if (parent != null) { + if (direction == FocusNavigationDirection.Previous && parent.CanFocus()) + { + return parent; + } + var siblings = parent.GetVisualChildren() .OfType() .Where(FocusExtensions.CanFocusDescendents); diff --git a/Tests/Perspex.Input.UnitTests/KeyboardNavigationTests_Arrows.cs b/Tests/Perspex.Input.UnitTests/KeyboardNavigationTests_Arrows.cs index 0bd1b0460e..1dfee5f1db 100644 --- a/Tests/Perspex.Input.UnitTests/KeyboardNavigationTests_Arrows.cs +++ b/Tests/Perspex.Input.UnitTests/KeyboardNavigationTests_Arrows.cs @@ -621,6 +621,26 @@ namespace Perspex.Input.UnitTests 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, FocusNavigationDirection.Up); + + Assert.Equal(top, result); + } + [Fact] public void Up_Cycle_Returns_Up_Control_In_Container() { @@ -777,7 +797,7 @@ namespace Perspex.Input.UnitTests } [Fact] - public void Up_Contained_Doesnt_Select_Child_Control() + public void Up_Contained_Doesnt_Return_Child_Control() { Decorator current; diff --git a/Tests/Perspex.Input.UnitTests/KeyboardNavigationTests_Tab.cs b/Tests/Perspex.Input.UnitTests/KeyboardNavigationTests_Tab.cs index 3214ac245c..1ab105ce70 100644 --- a/Tests/Perspex.Input.UnitTests/KeyboardNavigationTests_Tab.cs +++ b/Tests/Perspex.Input.UnitTests/KeyboardNavigationTests_Tab.cs @@ -758,6 +758,25 @@ namespace Perspex.Input.UnitTests Assert.Equal(next, result); } + [Fact] + public void Previous_Continue_Returns_Parent() + { + Button current; + + var top = new Decorator + { + Focusable = true, + Child = current = new Button + { + Name = "Button", + } + }; + + var result = KeyboardNavigationHandler.GetNext(current, FocusNavigationDirection.Previous); + + Assert.Equal(top, result); + } + [Fact] public void Previous_Cycle_Returns_Previous_Control_In_Container() {