Browse Source

Merge pull request #9731 from robloo/combobox-events

Add DropDownOpened and DropDownClosed events to ComboBox
pull/9763/head
Max Katz 3 years ago
committed by GitHub
parent
commit
293202cace
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 83
      src/Avalonia.Controls/ComboBox.cs

83
src/Avalonia.Controls/ComboBox.cs

@ -95,19 +95,26 @@ namespace Avalonia.Controls
{
ItemsPanelProperty.OverrideDefaultValue<ComboBox>(DefaultPanel);
FocusableProperty.OverrideDefaultValue<ComboBox>(true);
SelectedItemProperty.Changed.AddClassHandler<ComboBox>((x, e) => x.SelectedItemChanged(e));
KeyDownEvent.AddClassHandler<ComboBox>((x, e) => x.OnKeyDown(e), Interactivity.RoutingStrategies.Tunnel);
IsTextSearchEnabledProperty.OverrideDefaultValue<ComboBox>(true);
IsDropDownOpenProperty.Changed.AddClassHandler<ComboBox>((x, e) => x.DropdownChanged(e));
}
/// <summary>
/// Occurs after the drop-down (popup) list of the <see cref="ComboBox"/> closes.
/// </summary>
public event EventHandler? DropDownClosed;
/// <summary>
/// Occurs after the drop-down (popup) list of the <see cref="ComboBox"/> opens.
/// </summary>
public event EventHandler? DropDownOpened;
/// <summary>
/// Gets or sets a value indicating whether the dropdown is currently open.
/// </summary>
public bool IsDropDownOpen
{
get { return _isDropDownOpen; }
set { SetAndRaise(IsDropDownOpenProperty, ref _isDropDownOpen, value); }
get => _isDropDownOpen;
set => SetAndRaise(IsDropDownOpenProperty, ref _isDropDownOpen, value);
}
/// <summary>
@ -115,8 +122,8 @@ namespace Avalonia.Controls
/// </summary>
public double MaxDropDownHeight
{
get { return GetValue(MaxDropDownHeightProperty); }
set { SetValue(MaxDropDownHeightProperty, value); }
get => GetValue(MaxDropDownHeightProperty);
set => SetValue(MaxDropDownHeightProperty, value);
}
/// <summary>
@ -124,8 +131,8 @@ namespace Avalonia.Controls
/// </summary>
protected object? SelectionBoxItem
{
get { return _selectionBoxItem; }
set { SetAndRaise(SelectionBoxItemProperty, ref _selectionBoxItem, value); }
get => _selectionBoxItem;
set => SetAndRaise(SelectionBoxItemProperty, ref _selectionBoxItem, value);
}
/// <summary>
@ -133,8 +140,8 @@ namespace Avalonia.Controls
/// </summary>
public string? PlaceholderText
{
get { return GetValue(PlaceholderTextProperty); }
set { SetValue(PlaceholderTextProperty, value); }
get => GetValue(PlaceholderTextProperty);
set => SetValue(PlaceholderTextProperty, value);
}
/// <summary>
@ -142,8 +149,8 @@ namespace Avalonia.Controls
/// </summary>
public IBrush? PlaceholderForeground
{
get { return GetValue(PlaceholderForegroundProperty); }
set { SetValue(PlaceholderForegroundProperty, value); }
get => GetValue(PlaceholderForegroundProperty);
set => SetValue(PlaceholderForegroundProperty, value);
}
/// <summary>
@ -151,8 +158,8 @@ namespace Avalonia.Controls
/// </summary>
public ItemVirtualizationMode VirtualizationMode
{
get { return GetValue(VirtualizationModeProperty); }
set { SetValue(VirtualizationModeProperty, value); }
get => GetValue(VirtualizationModeProperty);
set => SetValue(VirtualizationModeProperty, value);
}
/// <summary>
@ -160,8 +167,8 @@ namespace Avalonia.Controls
/// </summary>
public HorizontalAlignment HorizontalContentAlignment
{
get { return GetValue(HorizontalContentAlignmentProperty); }
set { SetValue(HorizontalContentAlignmentProperty, value); }
get => GetValue(HorizontalContentAlignmentProperty);
set => SetValue(HorizontalContentAlignmentProperty, value);
}
/// <summary>
@ -169,8 +176,8 @@ namespace Avalonia.Controls
/// </summary>
public VerticalAlignment VerticalContentAlignment
{
get { return GetValue(VerticalContentAlignmentProperty); }
set { SetValue(VerticalContentAlignmentProperty, value); }
get => GetValue(VerticalContentAlignmentProperty);
set => SetValue(VerticalContentAlignmentProperty, value);
}
/// <inheritdoc/>
@ -182,6 +189,7 @@ namespace Avalonia.Controls
ComboBoxItem.ContentTemplateProperty);
}
/// <inheritdoc/>
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToVisualTree(e);
@ -239,7 +247,7 @@ namespace Avalonia.Controls
}
// This part of code is needed just to acquire initial focus, subsequent focus navigation will be done by ItemsControl.
else if (IsDropDownOpen && SelectedIndex < 0 && ItemCount > 0 &&
(e.Key == Key.Up || e.Key == Key.Down) && IsFocused == true)
(e.Key == Key.Up || e.Key == Key.Down) && IsFocused == true)
{
var firstChild = Presenter?.Panel?.Children.FirstOrDefault(c => CanFocus(c));
if (firstChild != null)
@ -309,12 +317,11 @@ namespace Avalonia.Controls
e.Handled = true;
}
}
PseudoClasses.Set(pcPressed, false);
base.OnPointerReleased(e);
}
/// <inheritdoc/>
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
@ -329,6 +336,22 @@ namespace Avalonia.Controls
_popup.Closed += PopupClosed;
}
/// <inheritdoc/>
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
if (change.Property == SelectedItemProperty)
{
UpdateSelectionBoxItem(change.NewValue);
TryFocusSelectedItem();
}
else if (change.Property == IsDropDownOpenProperty)
{
PseudoClasses.Set(pcDropdownOpen, change.GetNewValue<bool>());
}
base.OnPropertyChanged(change);
}
protected override AutomationPeer OnCreateAutomationPeer()
{
return new ComboBoxAutomationPeer(this);
@ -350,6 +373,8 @@ namespace Avalonia.Controls
{
Focus();
}
DropDownClosed?.Invoke(this, EventArgs.Empty);
}
private void PopupOpened(object? sender, EventArgs e)
@ -379,6 +404,8 @@ namespace Avalonia.Controls
}
UpdateFlowDirection();
DropDownOpened?.Invoke(this, EventArgs.Empty);
}
private void IsVisibleChanged(bool isVisible)
@ -389,12 +416,6 @@ namespace Avalonia.Controls
}
}
private void SelectedItemChanged(AvaloniaPropertyChangedEventArgs e)
{
UpdateSelectionBoxItem(e.NewValue);
TryFocusSelectedItem();
}
private void TryFocusSelectedItem()
{
var selectedIndex = SelectedIndex;
@ -494,11 +515,5 @@ namespace Avalonia.Controls
MoveSelection(NavigationDirection.Previous, WrapSelection);
}
}
private void DropdownChanged(AvaloniaPropertyChangedEventArgs e)
{
bool newValue = e.GetNewValue<bool>();
PseudoClasses.Set(pcDropdownOpen, newValue);
}
}
}

Loading…
Cancel
Save