diff --git a/tests/Avalonia.Controls.UnitTests/TabControlTests.cs b/tests/Avalonia.Controls.UnitTests/TabControlTests.cs index 7440ee4858..15ba871e8c 100644 --- a/tests/Avalonia.Controls.UnitTests/TabControlTests.cs +++ b/tests/Avalonia.Controls.UnitTests/TabControlTests.cs @@ -5,8 +5,10 @@ using System.Linq; using Avalonia.Collections; using Avalonia.Controls.Presenters; using Avalonia.Controls.Primitives; +using Avalonia.Controls.Selection; using Avalonia.Controls.Templates; using Avalonia.Controls.Utils; +using Avalonia.Input; using Avalonia.LogicalTree; using Avalonia.Markup.Xaml; using Avalonia.Styling; @@ -413,6 +415,117 @@ namespace Avalonia.Controls.UnitTests } } + [Fact] + public void Tab_Navigation_Should_Move_To_First_TabItem_When_No_Anchor_Element_Selected() + { + var services = TestServices.StyledWindow.With( + focusManager: new FocusManager(), + keyboardDevice: () => new KeyboardDevice()); + using var app = UnitTestApplication.Start(services); + + var target = new TabControl + { + Template = TabControlTemplate(), + Items = + { + new TabItem { Header = "foo" }, + new TabItem { Header = "bar" }, + new TabItem { Header = "baz" }, + } + }; + + var button = new Button + { + Content = "Button", + [DockPanel.DockProperty] = Dock.Top, + }; + + var root = new TestRoot + { + Child = new DockPanel + { + Children = + { + button, + target, + } + } + }; + + var navigation = new KeyboardNavigationHandler(); + navigation.SetOwner(root); + + root.LayoutManager.ExecuteInitialLayoutPass(); + + button.Focus(); + RaiseKeyEvent(button, Key.Tab); + + var item = target.ContainerFromIndex(0); + Assert.Same(item, FocusManager.Instance.Current); + } + + [Fact] + public void Tab_Navigation_Should_Move_To_Anchor_TabItem() + { + var services = TestServices.StyledWindow.With( + focusManager: new FocusManager(), + keyboardDevice: () => new KeyboardDevice()); + using var app = UnitTestApplication.Start(services); + + var target = new TestTabControl + { + Template = TabControlTemplate(), + Items = + { + new TabItem { Header = "foo" }, + new TabItem { Header = "bar" }, + new TabItem { Header = "baz" }, + } + }; + + var button = new Button + { + Content = "Button", + [DockPanel.DockProperty] = Dock.Top, + }; + + var root = new TestRoot + { + Width = 1000, + Height = 1000, + Child = new DockPanel + { + Children = + { + button, + target, + } + } + }; + + var navigation = new KeyboardNavigationHandler(); + navigation.SetOwner(root); + + root.LayoutManager.ExecuteInitialLayoutPass(); + + button.Focus(); + target.Selection.AnchorIndex = 1; + RaiseKeyEvent(button, Key.Tab); + + var item = target.ContainerFromIndex(1); + Assert.Same(item, FocusManager.Instance.Current); + + RaiseKeyEvent(item, Key.Tab); + + Assert.Same(button, FocusManager.Instance.Current); + + target.Selection.AnchorIndex = 2; + RaiseKeyEvent(button, Key.Tab); + + item = target.ContainerFromIndex(2); + Assert.Same(item, FocusManager.Instance.Current); + } + private static IControlTemplate TabControlTemplate() { return new FuncControlTemplate((parent, scope) => @@ -452,6 +565,16 @@ namespace Avalonia.Controls.UnitTests target.Arrange(new Rect(target.DesiredSize)); } + private static void RaiseKeyEvent(Control target, Key key, KeyModifiers inputModifiers = 0) + { + target.RaiseEvent(new KeyEventArgs + { + RoutedEvent = InputElement.KeyDownEvent, + KeyModifiers = inputModifiers, + Key = key + }); + } + private static void ApplyTemplate(TabControl target) { target.ApplyTemplate(); @@ -479,5 +602,11 @@ namespace Avalonia.Controls.UnitTests public string Value { get; } } + + private class TestTabControl : TabControl, IStyleable + { + Type IStyleable.StyleKey => typeof(TabControl); + public new ISelectionModel Selection => base.Selection; + } } }