From 3e2d068b85b48e40a77f0f7bb9b429b568c04c62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Su=C3=A1rez?= Date: Wed, 20 May 2026 18:07:49 +0200 Subject: [PATCH] Fix CommandBar overflow labels when label position is collapsed (#21226) * Fix CommandBar overflow labels * Updated samples * Updated render test * Updated render test * Removed Render Tests --- .../CommandBarLabelPositionPage.xaml | 22 ++++- .../CommandBar/CommandBar.cs | 19 +++-- .../Controls/CommandBar.xaml | 28 +++++++ .../Controls/CommandBar.xaml | 28 +++++++ .../CommandBarTests.cs | 81 ++++++++++++++++++- .../Controls/CommandBarTests.cs | 1 + 6 files changed, 168 insertions(+), 11 deletions(-) diff --git a/samples/ControlCatalog/Pages/CommandBar/CommandBarLabelPositionPage.xaml b/samples/ControlCatalog/Pages/CommandBar/CommandBarLabelPositionPage.xaml index a4b23542d7..a0c38d96aa 100644 --- a/samples/ControlCatalog/Pages/CommandBar/CommandBarLabelPositionPage.xaml +++ b/samples/ControlCatalog/Pages/CommandBar/CommandBarLabelPositionPage.xaml @@ -6,6 +6,8 @@ M15,9H5V5H15M12,19A3,3 0 0,1 9,16A3,3 0 0,1 12,13A3,3 0 0,1 15,16A3,3 0 0,1 12,19M17,3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V7L17,3Z M18,16.08C17.24,16.08 16.56,16.38 16.04,16.85L8.91,12.7C8.96,12.47 9,12.24 9,12C9,11.76 8.96,11.53 8.91,11.3L15.96,7.19C16.5,7.69 17.21,8 18,8A3,3 0 0,0 21,5A3,3 0 0,0 18,2A3,3 0 0,0 15,5C15,5.24 15.04,5.47 15.09,5.7L8.04,9.81C7.5,9.31 6.79,9 6,9A3,3 0 0,0 3,12A3,3 0 0,0 6,15C6.79,15 7.5,14.69 8.04,14.19L15.16,18.34C15.11,18.55 15.08,18.77 15.08,19C15.08,20.61 16.39,21.91 18,21.91C19.61,21.91 20.92,20.61 20.92,19C20.92,17.39 19.61,16.08 18,16.08Z M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z + M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20M16,11V18.1L13.9,16L11.1,18.8L8.3,16L11.1,13.2L9,11.1L16,11Z + M19.43,12.98C19.47,12.66 19.5,12.34 19.5,12C19.5,11.66 19.47,11.33 19.42,11L21.54,9.34C21.73,9.19 21.78,8.92 21.66,8.7L19.66,5.24C19.54,5.02 19.29,4.93 19.06,5.02L16.56,6.03C16.04,5.63 15.5,5.3 14.87,5.05L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.05C8.5,5.3 7.96,5.64 7.44,6.03L4.94,5.02C4.71,4.93 4.46,5.02 4.34,5.24L2.34,8.7C2.21,8.92 2.27,9.19 2.46,9.34L4.58,11C4.53,11.33 4.5,11.66 4.5,12C4.5,12.34 4.53,12.66 4.57,12.98L2.45,14.64C2.26,14.79 2.21,15.06 2.33,15.28L4.33,18.74C4.45,18.96 4.7,19.05 4.93,18.96L7.43,17.95C7.95,18.35 8.5,18.68 9.12,18.93L9.49,21.56C9.54,21.8 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.95C15.5,18.7 16.04,18.36 16.56,17.97L19.06,18.98C19.29,19.07 19.54,18.98 19.66,18.76L21.66,15.3C21.78,15.08 21.73,14.81 21.54,14.66L19.43,12.98M12,15.5A3.5,3.5 0 1,1 12,8A3.5,3.5 0 0,1 12,15.5Z @@ -14,33 +16,45 @@ - + + + + + - + + + + + - - + + + + + + diff --git a/src/Avalonia.Controls/CommandBar/CommandBar.cs b/src/Avalonia.Controls/CommandBar/CommandBar.cs index 6b92a935ad..54f5e16398 100644 --- a/src/Avalonia.Controls/CommandBar/CommandBar.cs +++ b/src/Avalonia.Controls/CommandBar/CommandBar.cs @@ -427,6 +427,8 @@ namespace Avalonia.Controls else if (change.Property == DefaultLabelPositionProperty) { ApplyLabelPositionToChildren(); + if (IsDynamicOverflowEnabled) + UpdateDynamicOverflow(); } else if (change.Property == OverflowButtonVisibilityProperty) { @@ -733,8 +735,11 @@ namespace Avalonia.Controls } } - private static void SetOverflowMode(ICommandBarElement element, bool inOverflow) - => element.IsInOverflow = inOverflow; + private void SetOverflowMode(ICommandBarElement element, bool inOverflow) + { + element.IsInOverflow = inOverflow; + ApplyLabelPositionToElement(element); + } private static int GetDynamicOverflowOrder(ICommandBarElement element) => element switch { @@ -757,12 +762,16 @@ namespace Avalonia.Controls private void ApplyLabelPositionToElement(ICommandBarElement element) { - element.IsCompact = DefaultLabelPosition == CommandBarDefaultLabelPosition.Collapsed; + var labelPosition = element.IsInOverflow + ? CommandBarDefaultLabelPosition.Right + : DefaultLabelPosition; + + element.IsCompact = labelPosition == CommandBarDefaultLabelPosition.Collapsed; if (element is CommandBarButton abb) - abb.LabelPosition = DefaultLabelPosition; + abb.LabelPosition = labelPosition; else if (element is CommandBarToggleButton atb) - atb.LabelPosition = DefaultLabelPosition; + atb.LabelPosition = labelPosition; } private void UpdateStickyBehavior() diff --git a/src/Avalonia.Themes.Fluent/Controls/CommandBar.xaml b/src/Avalonia.Themes.Fluent/Controls/CommandBar.xaml index b76acab856..c1f8c16a2d 100644 --- a/src/Avalonia.Themes.Fluent/Controls/CommandBar.xaml +++ b/src/Avalonia.Themes.Fluent/Controls/CommandBar.xaml @@ -104,7 +104,21 @@ + + @@ -191,7 +205,21 @@ + + diff --git a/src/Avalonia.Themes.Simple/Controls/CommandBar.xaml b/src/Avalonia.Themes.Simple/Controls/CommandBar.xaml index dd073c0f38..0bc6362619 100644 --- a/src/Avalonia.Themes.Simple/Controls/CommandBar.xaml +++ b/src/Avalonia.Themes.Simple/Controls/CommandBar.xaml @@ -98,7 +98,21 @@ + + @@ -186,7 +200,21 @@ + + diff --git a/tests/Avalonia.Controls.UnitTests/CommandBarTests.cs b/tests/Avalonia.Controls.UnitTests/CommandBarTests.cs index a7996a46ca..e886bea535 100644 --- a/tests/Avalonia.Controls.UnitTests/CommandBarTests.cs +++ b/tests/Avalonia.Controls.UnitTests/CommandBarTests.cs @@ -905,7 +905,7 @@ public class CommandBarLabelPositionTests : ScopedTestBase } [Fact] - public void DefaultLabelPosition_Collapsed_AppliesToSecondaryCommands() + public void DefaultLabelPosition_Collapsed_DoesNotCompactSecondaryCommands() { var cb = new CommandBar(); var btn = new CommandBarButton(); @@ -913,7 +913,84 @@ public class CommandBarLabelPositionTests : ScopedTestBase cb.DefaultLabelPosition = CommandBarDefaultLabelPosition.Collapsed; - Assert.True(btn.IsCompact); + Assert.True(btn.IsInOverflow); + Assert.False(btn.IsCompact); + Assert.Equal(CommandBarDefaultLabelPosition.Right, btn.LabelPosition); + } + + [Fact] + public void NewSecondaryCommand_GetsOverflowLabelPosition_WhenAlreadyCollapsed() + { + var cb = new CommandBar { DefaultLabelPosition = CommandBarDefaultLabelPosition.Collapsed }; + + var btn = new CommandBarButton(); + cb.SecondaryCommands!.Add(btn); + + Assert.True(btn.IsInOverflow); + Assert.False(btn.IsCompact); + Assert.Equal(CommandBarDefaultLabelPosition.Right, btn.LabelPosition); + } + + [Fact] + public void DefaultLabelPosition_Collapsed_DoesNotCompactSecondaryToggleButton() + { + var cb = new CommandBar(); + var toggle = new CommandBarToggleButton(); + cb.SecondaryCommands!.Add(toggle); + + cb.DefaultLabelPosition = CommandBarDefaultLabelPosition.Collapsed; + + Assert.True(toggle.IsInOverflow); + Assert.False(toggle.IsCompact); + Assert.Equal(CommandBarDefaultLabelPosition.Right, toggle.LabelPosition); + } + + [Fact] + public void DefaultLabelPosition_Collapsed_DoesNotCompactOverflowedPrimaryCommand() + { + var cb = new CommandBar + { + DefaultLabelPosition = CommandBarDefaultLabelPosition.Collapsed, + IsDynamicOverflowEnabled = true + }; + cb.Measure(new Size(81, double.PositiveInfinity)); + + var visible = new CommandBarButton(); + var overflowed = new CommandBarButton(); + cb.PrimaryCommands!.Add(visible); + cb.PrimaryCommands!.Add(overflowed); + + Assert.Contains(visible, cb.VisiblePrimaryCommands); + Assert.True(visible.IsCompact); + Assert.Equal(CommandBarDefaultLabelPosition.Collapsed, visible.LabelPosition); + Assert.Contains(overflowed, cb.OverflowItems); + Assert.True(overflowed.IsInOverflow); + Assert.False(overflowed.IsCompact); + Assert.Equal(CommandBarDefaultLabelPosition.Right, overflowed.LabelPosition); + } + + [Fact] + public void OverflowedPrimaryCommand_ReappliesDefaultLabelPosition_WhenRestored() + { + var cb = new CommandBar + { + DefaultLabelPosition = CommandBarDefaultLabelPosition.Collapsed, + IsDynamicOverflowEnabled = true + }; + cb.Measure(new Size(81, double.PositiveInfinity)); + + var visible = new CommandBarButton(); + var overflowed = new CommandBarButton(); + cb.PrimaryCommands!.Add(visible); + cb.PrimaryCommands!.Add(overflowed); + Assert.Contains(overflowed, cb.OverflowItems); + + cb.Measure(new Size(400, double.PositiveInfinity)); + + Assert.Contains(overflowed, cb.VisiblePrimaryCommands); + Assert.False(overflowed.IsInOverflow); + Assert.True(overflowed.IsCompact); + Assert.Equal(CommandBarDefaultLabelPosition.Collapsed, overflowed.LabelPosition); } [Fact] diff --git a/tests/Avalonia.RenderTests/Controls/CommandBarTests.cs b/tests/Avalonia.RenderTests/Controls/CommandBarTests.cs index ebef5ce419..2cf3991a6d 100644 --- a/tests/Avalonia.RenderTests/Controls/CommandBarTests.cs +++ b/tests/Avalonia.RenderTests/Controls/CommandBarTests.cs @@ -142,5 +142,6 @@ namespace Avalonia.Direct2D1.RenderTests.Controls await RenderToFile(target); CompareImages(skipImmediate: true); } + } }