Browse Source

Merge pull request #10281 from AvaloniaUI/fixes/10232-combobox-keyboard

Fix ComboBox keyboard selection when drop-down closed
pull/10289/head
Max Katz 3 years ago
committed by GitHub
parent
commit
4d4cb02858
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      .ncrunch/Avalonia.UnitTests.v3.ncrunchproject
  2. 5
      .ncrunch/GpuInterop.v3.ncrunchproject
  3. 1
      Avalonia.Desktop.slnf
  4. 1
      samples/IntegrationTestApp/MainWindow.axaml
  5. 55
      src/Avalonia.Controls/ComboBox.cs
  6. 61
      tests/Avalonia.IntegrationTests.Appium/ComboBoxTests.cs

5
.ncrunch/Avalonia.UnitTests.v3.ncrunchproject

@ -0,0 +1,5 @@
<ProjectConfiguration>
<Settings>
<XUnit2Enabled>False</XUnit2Enabled>
</Settings>
</ProjectConfiguration>

5
.ncrunch/GpuInterop.v3.ncrunchproject

@ -0,0 +1,5 @@
<ProjectConfiguration>
<Settings>
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
</Settings>
</ProjectConfiguration>

1
Avalonia.Desktop.slnf

@ -45,6 +45,7 @@
"tests\\Avalonia.Base.UnitTests\\Avalonia.Base.UnitTests.csproj",
"tests\\Avalonia.Benchmarks\\Avalonia.Benchmarks.csproj",
"tests\\Avalonia.Controls.DataGrid.UnitTests\\Avalonia.Controls.DataGrid.UnitTests.csproj",
"tests\\Avalonia.Controls.ItemsRepeater.UnitTests\\Avalonia.Controls.ItemsRepeater.UnitTests.csproj",
"tests\\Avalonia.Controls.UnitTests\\Avalonia.Controls.UnitTests.csproj",
"tests\\Avalonia.DesignerSupport.TestApp\\Avalonia.DesignerSupport.TestApp.csproj",
"tests\\Avalonia.DesignerSupport.Tests\\Avalonia.DesignerSupport.Tests.csproj",

1
samples/IntegrationTestApp/MainWindow.axaml

@ -70,6 +70,7 @@
<ComboBoxItem>Item 0</ComboBoxItem>
<ComboBoxItem>Item 1</ComboBoxItem>
</ComboBox>
<CheckBox Name="ComboBoxWrapSelection" IsChecked="{Binding #BasicComboBox.WrapSelection}">Wrap Selection</CheckBox>
<Button Name="ComboBoxSelectionClear">Clear Selection</Button>
<Button Name="ComboBoxSelectFirst">Select First</Button>
</StackPanel>

55
src/Avalonia.Controls/ComboBox.cs

@ -1,19 +1,19 @@
using System;
using System.Diagnostics;
using System.Linq;
using Avalonia.Automation.Peers;
using Avalonia.Reactive;
using Avalonia.Controls.Generators;
using Avalonia.Controls.Mixins;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Selection;
using Avalonia.Controls.Shapes;
using Avalonia.Controls.Templates;
using Avalonia.Controls.Utils;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Layout;
using Avalonia.Media;
using Avalonia.Reactive;
using Avalonia.VisualTree;
using Avalonia.Controls.Metadata;
namespace Avalonia.Controls
{
@ -219,7 +219,7 @@ namespace Avalonia.Controls
}
else if (e.Key == Key.Up)
{
SelectPrev();
SelectPrevious();
e.Handled = true;
}
}
@ -250,7 +250,7 @@ namespace Avalonia.Controls
if (e.Delta.Y < 0)
SelectNext();
else
SelectPrev();
SelectPrevious();
e.Handled = true;
}
@ -478,19 +478,40 @@ namespace Avalonia.Controls
}
}
private void SelectNext()
{
if (ItemCount >= 1)
{
MoveSelection(NavigationDirection.Next, WrapSelection);
}
}
private void SelectNext() => MoveSelection(SelectedIndex, 1, WrapSelection);
private void SelectPrevious() => MoveSelection(SelectedIndex, -1, WrapSelection);
private void SelectPrev()
private void MoveSelection(int startIndex, int step, bool wrap)
{
if (ItemCount >= 1)
static bool IsSelectable(object? o) => (o as AvaloniaObject)?.GetValue(IsEnabledProperty) ?? true;
var count = ItemCount;
for (int i = startIndex + step; i != startIndex; i += step)
{
MoveSelection(NavigationDirection.Previous, WrapSelection);
if (i < 0 || i >= count)
{
if (wrap)
{
if (i < 0)
i += count;
else if (i >= count)
i %= count;
}
else
{
return;
}
}
var item = ItemsView[i];
var container = ContainerFromIndex(i);
if (IsSelectable(item) && IsSelectable(container))
{
SelectedIndex = i;
break;
}
}
}
}

61
tests/Avalonia.IntegrationTests.Appium/ComboBoxTests.cs

@ -47,7 +47,64 @@ namespace Avalonia.IntegrationTests.Appium
}
[PlatformFact(TestPlatforms.Windows)]
public void Can_Change_Selection_With_Keyboard()
public void Can_Change_Selection_With_Keyboard_When_Closed()
{
var comboBox = _session.FindElementByAccessibilityId("BasicComboBox");
var wrap = _session.FindElementByAccessibilityId("ComboBoxWrapSelection");
if (wrap.GetIsChecked() != false)
wrap.Click();
_session.FindElementByAccessibilityId("ComboBoxSelectionClear").Click();
comboBox.SendKeys(Keys.ArrowDown);
Assert.Equal("Item 0", comboBox.GetComboBoxValue());
comboBox.SendKeys(Keys.ArrowDown);
Assert.Equal("Item 1", comboBox.GetComboBoxValue());
comboBox.SendKeys(Keys.ArrowDown);
Assert.Equal("Item 1", comboBox.GetComboBoxValue());
comboBox.SendKeys(Keys.ArrowUp);
Assert.Equal("Item 0", comboBox.GetComboBoxValue());
comboBox.SendKeys(Keys.ArrowUp);
Assert.Equal("Item 0", comboBox.GetComboBoxValue());
}
[PlatformFact(TestPlatforms.Windows)]
public void Can_Change_Wrapping_Selection_With_Keyboard_When_Closed()
{
var comboBox = _session.FindElementByAccessibilityId("BasicComboBox");
var wrap = _session.FindElementByAccessibilityId("ComboBoxWrapSelection");
if (wrap.GetIsChecked() != true)
wrap.Click();
_session.FindElementByAccessibilityId("ComboBoxSelectionClear").Click();
comboBox.SendKeys(Keys.ArrowDown);
Assert.Equal("Item 0", comboBox.GetComboBoxValue());
comboBox.SendKeys(Keys.ArrowDown);
Assert.Equal("Item 1", comboBox.GetComboBoxValue());
comboBox.SendKeys(Keys.ArrowDown);
Assert.Equal("Item 0", comboBox.GetComboBoxValue());
comboBox.SendKeys(Keys.ArrowDown);
Assert.Equal("Item 1", comboBox.GetComboBoxValue());
comboBox.SendKeys(Keys.ArrowUp);
Assert.Equal("Item 0", comboBox.GetComboBoxValue());
comboBox.SendKeys(Keys.ArrowUp);
Assert.Equal("Item 1", comboBox.GetComboBoxValue());
}
[PlatformFact(TestPlatforms.Windows)]
public void Can_Change_Selection_When_Open_With_Keyboard()
{
var comboBox = _session.FindElementByAccessibilityId("BasicComboBox");
@ -64,7 +121,7 @@ namespace Avalonia.IntegrationTests.Appium
}
[PlatformFact(TestPlatforms.Windows)]
public void Can_Change_Selection_With_Keyboard_From_Unselected()
public void Can_Change_Selection_When_Open_With_Keyboard_From_Unselected()
{
var comboBox = _session.FindElementByAccessibilityId("BasicComboBox");

Loading…
Cancel
Save