using Avalonia.Controls; using Avalonia.Input; using Xunit; namespace Avalonia.Base.UnitTests.Input { public class KeyboardNavigationTests_Custom { [Fact] public void Tab_Should_Custom_Navigate_Within_Children() { Button current; Button next; var target = new CustomNavigatingStackPanel { Children = { (current = new Button { Content = "Button 1" }), new Button { Content = "Button 2" }, (next = new Button { Content = "Button 3" }), }, NextControl = next, }; var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Next); Assert.Same(next, result); } [Fact] public void Right_Should_Custom_Navigate_Within_Children() { Button current; Button next; var target = new CustomNavigatingStackPanel { Children = { (current = new Button { Content = "Button 1" }), new Button { Content = "Button 2" }, (next = new Button { Content = "Button 3" }), }, NextControl = next, }; var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Right); Assert.Same(next, result); } [Fact] public void Tab_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, } }; var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Next); Assert.Same(next, result); } [Fact] public void Tab_Should_Custom_Navigate_From_Outside_When_Wrapping() { 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 { [KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Cycle, Children = { target, (current = new Button { Content = "Outside" }), } }; var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Next); Assert.Same(next, result); } [Fact] public void ShiftTab_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 { [KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Cycle, Children = { (current = new Button { Content = "Outside" }), target, } }; var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Previous); Assert.Same(next, result); } [Fact] public void ShiftTab_Should_Navigate_Outside_When_Null_Returned_As_Next() { Button current; Button next; var target = new CustomNavigatingStackPanel { Children = { new Button { Content = "Button 1" }, (current = new Button { Content = "Button 2" }), new Button { Content = "Button 3" }, }, }; var root = new StackPanel { [KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Cycle, Children = { target, (next = new Button { Content = "Outside" }), } }; var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Previous); Assert.Same(next, result); } [Fact] public void Tab_Should_Navigate_Outside_When_Null_Returned_As_Next() { Button current; Button next; var target = new CustomNavigatingStackPanel { Children = { new Button { Content = "Button 1" }, (current = new Button { Content = "Button 2" }), new Button { Content = "Button 3" }, }, }; var root = new StackPanel { [KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Cycle, Children = { target, (next = new Button { Content = "Outside" }), } }; var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Next); Assert.Same(next, result); } private class CustomNavigatingStackPanel : StackPanel, ICustomKeyboardNavigation { public bool CustomNavigates { get; set; } = true; public IInputElement NextControl { get; set; } public (bool handled, IInputElement next) GetNext(IInputElement element, NavigationDirection direction) { return (CustomNavigates, NextControl); } } } }