mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-28 06:07:28 +08:00
106 lines
3.6 KiB
C#
106 lines
3.6 KiB
C#
using AtomUI.Controls.Data;
|
|
using Avalonia.Input;
|
|
using Avalonia.Threading;
|
|
using Avalonia.VisualTree;
|
|
using Shouldly;
|
|
using Xunit;
|
|
using AtomListViewItem = AtomUI.Desktop.Controls.ListViewItem;
|
|
using AvaloniaWindow = Avalonia.Controls.Window;
|
|
|
|
namespace AtomUI.Desktop.Controls.Tests.ListView;
|
|
|
|
public class ListViewKeyboardNavigationTests
|
|
{
|
|
static ListViewKeyboardNavigationTests()
|
|
{
|
|
AvaloniaTestApp.EnsureInitialized();
|
|
}
|
|
|
|
[Fact]
|
|
public void MoveSelection_Uses_The_Owning_TopLevel_FocusManager()
|
|
{
|
|
var firstList = CreateList("first-a", "first-b");
|
|
var secondList = CreateList("second-a", "second-b");
|
|
var firstWindow = new AvaloniaWindow { Content = firstList, Width = 300, Height = 200 };
|
|
var secondWindow = new AvaloniaWindow { Content = secondList, Width = 300, Height = 200 };
|
|
firstWindow.Show();
|
|
secondWindow.Show();
|
|
Dispatcher.UIThread.RunJobs();
|
|
|
|
try
|
|
{
|
|
var firstContainers = firstList.GetVisualDescendants().OfType<AtomListViewItem>().ToArray();
|
|
var secondContainers = secondList.GetVisualDescendants().OfType<AtomListViewItem>().ToArray();
|
|
firstContainers.Length.ShouldBe(2);
|
|
secondContainers.Length.ShouldBe(2);
|
|
|
|
firstContainers[1].Focus();
|
|
secondContainers[0].Focus();
|
|
Dispatcher.UIThread.RunJobs();
|
|
|
|
firstList.MoveDown().ShouldBeFalse(
|
|
"the first ListView must keep using its own TopLevel focus instead of the second window's focus");
|
|
}
|
|
finally
|
|
{
|
|
secondWindow.Close();
|
|
firstWindow.Close();
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void MoveSelection_Does_Not_Consume_Global_Focus_When_Detached()
|
|
{
|
|
var detached = CreateList("a", "b");
|
|
|
|
detached.MoveDown().ShouldBeFalse();
|
|
}
|
|
|
|
[Fact]
|
|
public void ListView_Uses_Public_TopLevel_Focus_While_AutoComplete_Keeps_Scoped_Helper()
|
|
{
|
|
var repoRoot = GetRepoRoot();
|
|
var listViewSource = File.ReadAllText(Path.Combine(
|
|
repoRoot,
|
|
"src/AtomUI.Desktop.Controls/ListView/ListView.Selecting.cs"));
|
|
var autoCompleteSource = File.ReadAllText(Path.Combine(
|
|
repoRoot,
|
|
"src/AtomUI.Desktop.Controls/AutoComplete/AbstractAutoComplete.cs"));
|
|
|
|
listViewSource.ShouldContain("TopLevel.GetTopLevel(this)?.FocusManager.GetFocusedElement()");
|
|
listViewSource.ShouldNotContain("FocusManagerReflectionExtensions.GetFocusManager(this)?.GetFocusedElement()");
|
|
autoCompleteSource.ShouldContain(
|
|
"FocusManagerReflectionExtensions.GetFocusManager(this)?.GetFocusedElement(scope)");
|
|
}
|
|
|
|
private static TestListView CreateList(params string[] labels) => new()
|
|
{
|
|
Width = 240,
|
|
Height = 160,
|
|
ItemsSource = labels.Select(label => new ListItemData { Content = label }).ToArray()
|
|
};
|
|
|
|
private static string GetRepoRoot()
|
|
{
|
|
var directory = new DirectoryInfo(AppContext.BaseDirectory);
|
|
while (directory is not null)
|
|
{
|
|
if (Directory.Exists(Path.Combine(directory.FullName, "src/AtomUI.Desktop.Controls")))
|
|
{
|
|
return directory.FullName;
|
|
}
|
|
|
|
directory = directory.Parent;
|
|
}
|
|
|
|
throw new DirectoryNotFoundException("Unable to locate the AtomUI repository root.");
|
|
}
|
|
|
|
private sealed class TestListView : AtomUI.Desktop.Controls.ListView
|
|
{
|
|
protected override Type StyleKeyOverride => typeof(AtomUI.Desktop.Controls.ListView);
|
|
|
|
internal bool MoveDown() => MoveSelection(NavigationDirection.Down);
|
|
}
|
|
}
|