Browse Source

Merge pull request #1589 from CommonGuy/improve-dropdown-keybehavior

Improve dropdown keybehavior
pull/1626/head
Steven Kirk 8 years ago
committed by GitHub
parent
commit
d42f6b4bd6
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 80
      src/Avalonia.Controls/DropDown.cs
  2. 35
      src/Avalonia.Controls/DropDownItem.cs

80
src/Avalonia.Controls/DropDown.cs

@ -6,7 +6,6 @@ using Avalonia.Controls.Generators;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Shapes;
using Avalonia.Input;
using Avalonia.Layout;
using Avalonia.LogicalTree;
using Avalonia.Media;
using Avalonia.VisualTree;
@ -51,6 +50,7 @@ namespace Avalonia.Controls
{
FocusableProperty.OverrideDefaultValue<DropDown>(true);
SelectedItemProperty.Changed.AddClassHandler<DropDown>(x => x.SelectedItemChanged);
KeyDownEvent.AddClassHandler<DropDown>(x => x.OnKeyDown, Interactivity.RoutingStrategies.Tunnel);
}
/// <summary>
@ -96,54 +96,46 @@ namespace Avalonia.Controls
this.UpdateSelectionBoxItem(this.SelectedItem);
}
protected override void OnGotFocus(GotFocusEventArgs e)
{
base.OnGotFocus(e);
if (!e.Handled && e.NavigationMethod == NavigationMethod.Directional)
{
e.Handled = UpdateSelectionFromEventSource(e.Source);
}
}
/// <inheritdoc/>
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (!e.Handled)
if (e.Handled)
return;
if (e.Key == Key.F4 ||
((e.Key == Key.Down || e.Key == Key.Up) && ((e.Modifiers & InputModifiers.Alt) != 0)))
{
if (e.Key == Key.F4 ||
((e.Key == Key.Down || e.Key == Key.Up) && ((e.Modifiers & InputModifiers.Alt) != 0)))
IsDropDownOpen = !IsDropDownOpen;
e.Handled = true;
}
else if (IsDropDownOpen && e.Key == Key.Escape)
{
IsDropDownOpen = false;
e.Handled = true;
}
else if (IsDropDownOpen && e.Key == Key.Enter)
{
SelectFocusedItem();
IsDropDownOpen = false;
e.Handled = true;
}
else if (!IsDropDownOpen)
{
if (e.Key == Key.Down)
{
IsDropDownOpen = !IsDropDownOpen;
if (++SelectedIndex >= ItemCount)
SelectedIndex = 0;
e.Handled = true;
}
else if (IsDropDownOpen && (e.Key == Key.Escape || e.Key == Key.Enter))
else if (e.Key == Key.Up)
{
IsDropDownOpen = false;
e.Handled = true;
}
if (--SelectedIndex < 0)
SelectedIndex = ItemCount - 1;
if (!IsDropDownOpen)
{
if (e.Key == Key.Down)
{
if (SelectedIndex == -1)
SelectedIndex = 0;
if (++SelectedIndex >= ItemCount)
SelectedIndex = 0;
e.Handled = true;
}
else if (e.Key == Key.Up)
{
if (--SelectedIndex < 0)
SelectedIndex = ItemCount - 1;
e.Handled = true;
}
e.Handled = true;
}
}
}
@ -230,5 +222,17 @@ namespace Avalonia.Controls
SelectionBoxItem = item;
}
}
private void SelectFocusedItem()
{
foreach (ItemContainerInfo dropdownItem in ItemContainerGenerator.Containers)
{
if (dropdownItem.ContainerControl.IsFocused)
{
SelectedIndex = dropdownItem.Index;
break;
}
}
}
}
}

35
src/Avalonia.Controls/DropDownItem.cs

@ -1,12 +1,45 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
namespace Avalonia.Controls
{
/// <summary>
/// A selectable item in a <see cref="DropDown"/>.
/// </summary>
public class DropDownItem : ListBoxItem
public class DropDownItem : ContentControl, ISelectable
{
/// <summary>
/// Defines the <see cref="IsSelected"/> property.
/// </summary>
public static readonly StyledProperty<bool> IsSelectedProperty =
AvaloniaProperty.Register<DropDownItem, bool>(nameof(IsSelected));
/// <summary>
/// Initializes static members of the <see cref="DropDownItem"/> class.
/// </summary>
static DropDownItem()
{
FocusableProperty.OverrideDefaultValue<DropDownItem>(true);
IsFocusedProperty.Changed.Subscribe(x =>
{
var sender = x.Sender as IControl;
if (sender != null)
{
((IPseudoClasses)sender.Classes).Set(":selected", (bool)x.NewValue);
}
});
}
/// <summary>
/// Gets or sets the selection state of the item.
/// </summary>
public bool IsSelected
{
get { return GetValue(IsSelectedProperty); }
set { SetValue(IsSelectedProperty, value); }
}
}
}

Loading…
Cancel
Save