|
|
|
@ -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); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|