diff --git a/src/Avalonia.Controls/ComboBox.cs b/src/Avalonia.Controls/ComboBox.cs index 05be5ad00d..54196bdf1a 100644 --- a/src/Avalonia.Controls/ComboBox.cs +++ b/src/Avalonia.Controls/ComboBox.cs @@ -21,8 +21,11 @@ namespace Avalonia.Controls /// A drop-down list control. /// [TemplatePart("PART_Popup", typeof(Popup))] + [PseudoClasses(pcDropdownOpen, pcPressed)] public class ComboBox : SelectingItemsControl { + public const string pcDropdownOpen = ":dropdownopen"; + public const string pcPressed = ":pressed"; /// /// The default value for the property. /// @@ -95,6 +98,7 @@ namespace Avalonia.Controls SelectedItemProperty.Changed.AddClassHandler((x, e) => x.SelectedItemChanged(e)); KeyDownEvent.AddClassHandler((x, e) => x.OnKeyDown(e), Interactivity.RoutingStrategies.Tunnel); IsTextSearchEnabledProperty.OverrideDefaultValue(true); + IsDropDownOpenProperty.Changed.AddClassHandler((x, e) => x.DropdownChanged(e)); } /// @@ -267,6 +271,20 @@ namespace Avalonia.Controls } } + /// + protected override void OnPointerPressed(PointerPressedEventArgs e) + { + base.OnPointerPressed(e); + if(!e.Handled && e.Source is IVisual source) + { + if (_popup?.IsInsidePopup(source) == true) + { + return; + } + } + PseudoClasses.Set(pcPressed, true); + } + /// protected override void OnPointerReleased(PointerReleasedEventArgs e) { @@ -286,10 +304,12 @@ namespace Avalonia.Controls e.Handled = true; } } - + PseudoClasses.Set(pcPressed, false); base.OnPointerReleased(e); + } + /// protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { @@ -470,5 +490,11 @@ namespace Avalonia.Controls MoveSelection(NavigationDirection.Previous, WrapSelection); } } + + private void DropdownChanged(AvaloniaPropertyChangedEventArgs e) + { + bool newValue = e.GetNewValue(); + PseudoClasses.Set(pcDropdownOpen, newValue); + } } } diff --git a/src/Avalonia.Themes.Fluent/Controls/ComboBox.xaml b/src/Avalonia.Themes.Fluent/Controls/ComboBox.xaml index af3b5bc51e..4aa0ddc23a 100644 --- a/src/Avalonia.Themes.Fluent/Controls/ComboBox.xaml +++ b/src/Avalonia.Themes.Fluent/Controls/ComboBox.xaml @@ -57,17 +57,8 @@ - - + - diff --git a/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs b/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs index aa32af7e51..21438543d5 100644 --- a/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs @@ -29,11 +29,36 @@ namespace Avalonia.Controls.UnitTests _helper.Down(target); _helper.Up(target); Assert.True(target.IsDropDownOpen); + Assert.True(target.Classes.Contains(ComboBox.pcDropdownOpen)); _helper.Down(target); _helper.Up(target); Assert.False(target.IsDropDownOpen); + Assert.True(!target.Classes.Contains(ComboBox.pcDropdownOpen)); + } + + [Fact] + public void Clicking_On_Control_PseudoClass() + { + var target = new ComboBox + { + Items = new[] { "Foo", "Bar" }, + }; + + _helper.Down(target); + Assert.True(target.Classes.Contains(ComboBox.pcPressed)); + _helper.Up(target); + Assert.True(!target.Classes.Contains(ComboBox.pcPressed)); + Assert.True(target.Classes.Contains(ComboBox.pcDropdownOpen)); + + _helper.Down(target); + Assert.True(target.Classes.Contains(ComboBox.pcPressed)); + _helper.Up(target); + Assert.True(!target.Classes.Contains(ComboBox.pcPressed)); + + Assert.False(target.IsDropDownOpen); + Assert.True(!target.Classes.Contains(ComboBox.pcDropdownOpen)); } [Fact]