A cross-platform UI framework for .NET
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1520 lines
48 KiB

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.LogicalTree;
using Avalonia.Threading;
using Avalonia.UnitTests;
using Avalonia.VisualTree;
using Xunit;
namespace Avalonia.Controls.UnitTests;
public class CommandBarButtonTests : ScopedTestBase
{
[Fact]
public void Label_DefaultIsNull()
=> Assert.Null(new CommandBarButton().Label);
[Fact]
public void Label_RoundTrip()
{
var btn = new CommandBarButton { Label = "Save" };
Assert.Equal("Save", btn.Label);
}
[Fact]
public void Icon_DefaultIsNull()
=> Assert.Null(new CommandBarButton().Icon);
[Fact]
public void Icon_RoundTrip()
{
var btn = new CommandBarButton();
var icon = new object();
btn.Icon = icon;
Assert.Same(icon, btn.Icon);
}
[Fact]
public void IsCompact_DefaultIsFalse()
=> Assert.False(new CommandBarButton().IsCompact);
[Fact]
public void IsCompact_RoundTrip()
{
var btn = new CommandBarButton { IsCompact = true };
Assert.True(btn.IsCompact);
}
[Fact]
public void DynamicOverflowOrder_DefaultIsZero()
=> Assert.Equal(0, new CommandBarButton().DynamicOverflowOrder);
[Fact]
public void DynamicOverflowOrder_RoundTrip()
{
var btn = new CommandBarButton { DynamicOverflowOrder = 3 };
Assert.Equal(3, btn.DynamicOverflowOrder);
}
[Fact]
public void LabelPosition_DefaultIsBottom()
=> Assert.Equal(CommandBarDefaultLabelPosition.Bottom, new CommandBarButton().LabelPosition);
[Fact]
public void LabelPosition_RoundTrip()
{
var btn = new CommandBarButton { LabelPosition = CommandBarDefaultLabelPosition.Right };
Assert.Equal(CommandBarDefaultLabelPosition.Right, btn.LabelPosition);
}
[Fact]
public void IsInOverflow_DefaultIsFalse()
=> Assert.False(new CommandBarButton().IsInOverflow);
[Fact]
public void IsInOverflow_RoundTrip()
{
var btn = new CommandBarButton { IsInOverflow = true };
Assert.True(btn.IsInOverflow);
}
[Fact]
public void ImplementsICommandBarElement()
=> Assert.IsAssignableFrom<ICommandBarElement>(new CommandBarButton());
[Fact]
public void ICommandBarElement_IsCompact_ReadWrite()
{
ICommandBarElement elem = new CommandBarButton();
elem.IsCompact = true;
Assert.True(elem.IsCompact);
}
[Fact]
public void Command_DefaultIsNull()
=> Assert.Null(new CommandBarButton().Command);
[Fact]
public void CommandParameter_DefaultIsNull()
=> Assert.Null(new CommandBarButton().CommandParameter);
[Fact]
public void Command_RoundTrip()
{
var btn = new CommandBarButton();
var cmd = new DelegateCommand(_ => { });
btn.Command = cmd;
Assert.Same(cmd, btn.Command);
}
[Fact]
public void CommandParameter_RoundTrip()
{
var btn = new CommandBarButton { CommandParameter = "param" };
Assert.Equal("param", btn.CommandParameter);
}
}
public class CommandBarToggleButtonTests : ScopedTestBase
{
[Fact]
public void Label_DefaultIsNull()
=> Assert.Null(new CommandBarToggleButton().Label);
[Fact]
public void Label_RoundTrip()
{
var btn = new CommandBarToggleButton { Label = "Bold" };
Assert.Equal("Bold", btn.Label);
}
[Fact]
public void Icon_DefaultIsNull()
=> Assert.Null(new CommandBarToggleButton().Icon);
[Fact]
public void IsCompact_DefaultIsFalse()
=> Assert.False(new CommandBarToggleButton().IsCompact);
[Fact]
public void IsCompact_RoundTrip()
{
var btn = new CommandBarToggleButton { IsCompact = true };
Assert.True(btn.IsCompact);
}
[Fact]
public void DynamicOverflowOrder_DefaultIsZero()
=> Assert.Equal(0, new CommandBarToggleButton().DynamicOverflowOrder);
[Fact]
public void DynamicOverflowOrder_RoundTrip()
{
var btn = new CommandBarToggleButton { DynamicOverflowOrder = 5 };
Assert.Equal(5, btn.DynamicOverflowOrder);
}
[Fact]
public void LabelPosition_DefaultIsBottom()
=> Assert.Equal(CommandBarDefaultLabelPosition.Bottom, new CommandBarToggleButton().LabelPosition);
[Fact]
public void LabelPosition_RoundTrip()
{
var btn = new CommandBarToggleButton { LabelPosition = CommandBarDefaultLabelPosition.Collapsed };
Assert.Equal(CommandBarDefaultLabelPosition.Collapsed, btn.LabelPosition);
}
[Fact]
public void IsInOverflow_DefaultIsFalse()
=> Assert.False(new CommandBarToggleButton().IsInOverflow);
[Fact]
public void ImplementsICommandBarElement()
=> Assert.IsAssignableFrom<ICommandBarElement>(new CommandBarToggleButton());
[Fact]
public void ICommandBarElement_IsCompact_ReadWrite()
{
ICommandBarElement elem = new CommandBarToggleButton();
elem.IsCompact = true;
Assert.True(elem.IsCompact);
}
[Fact]
public void Command_DefaultIsNull()
=> Assert.Null(new CommandBarToggleButton().Command);
[Fact]
public void Command_RoundTrip()
{
var btn = new CommandBarToggleButton();
var cmd = new DelegateCommand(_ => { });
btn.Command = cmd;
Assert.Same(cmd, btn.Command);
}
[Fact]
public void CommandParameter_RoundTrip()
{
var btn = new CommandBarToggleButton { CommandParameter = 42 };
Assert.Equal(42, btn.CommandParameter);
}
}
public class CommandBarSeparatorTests : ScopedTestBase
{
[Fact]
public void IsCompact_DefaultIsFalse()
=> Assert.False(new CommandBarSeparator().IsCompact);
[Fact]
public void IsCompact_RoundTrip()
{
var sep = new CommandBarSeparator { IsCompact = true };
Assert.True(sep.IsCompact);
}
[Fact]
public void IsInOverflow_DefaultIsFalse()
=> Assert.False(new CommandBarSeparator().IsInOverflow);
[Fact]
public void IsInOverflow_RoundTrip()
{
var sep = new CommandBarSeparator { IsInOverflow = true };
Assert.True(sep.IsInOverflow);
}
[Fact]
public void ImplementsICommandBarElement()
=> Assert.IsAssignableFrom<ICommandBarElement>(new CommandBarSeparator());
[Fact]
public void DerivesFromSeparator()
=> Assert.IsAssignableFrom<Separator>(new CommandBarSeparator());
[Fact]
public void ICommandBarElement_IsCompact_ReadWrite()
{
ICommandBarElement elem = new CommandBarSeparator();
elem.IsCompact = true;
Assert.True(elem.IsCompact);
}
}
public class CommandBarEnumTests : ScopedTestBase
{
[Fact]
public void LabelPosition_Bottom_IsZero()
=> Assert.Equal(0, (int)CommandBarDefaultLabelPosition.Bottom);
[Fact]
public void LabelPosition_Right_IsOne()
=> Assert.Equal(1, (int)CommandBarDefaultLabelPosition.Right);
[Fact]
public void LabelPosition_Collapsed_IsTwo()
=> Assert.Equal(2, (int)CommandBarDefaultLabelPosition.Collapsed);
[Fact]
public void OverflowButtonVisibility_Auto_IsZero()
=> Assert.Equal(0, (int)CommandBarOverflowButtonVisibility.Auto);
[Fact]
public void OverflowButtonVisibility_Visible_IsOne()
=> Assert.Equal(1, (int)CommandBarOverflowButtonVisibility.Visible);
[Fact]
public void OverflowButtonVisibility_Collapsed_IsTwo()
=> Assert.Equal(2, (int)CommandBarOverflowButtonVisibility.Collapsed);
}
public class CommandBarDefaultsTests : ScopedTestBase
{
[Fact]
public void DefaultLabelPosition_IsBottom()
=> Assert.Equal(CommandBarDefaultLabelPosition.Bottom, new CommandBar().DefaultLabelPosition);
[Fact]
public void OverflowButtonVisibility_DefaultIsAuto()
=> Assert.Equal(CommandBarOverflowButtonVisibility.Auto, new CommandBar().OverflowButtonVisibility);
[Fact]
public void IsOpen_DefaultIsFalse()
=> Assert.False(new CommandBar().IsOpen);
[Fact]
public void IsSticky_DefaultIsFalse()
=> Assert.False(new CommandBar().IsSticky);
[Fact]
public void IsDynamicOverflowEnabled_DefaultIsFalse()
=> Assert.False(new CommandBar().IsDynamicOverflowEnabled);
[Fact]
public void HasSecondaryCommands_DefaultIsFalse()
=> Assert.False(new CommandBar().HasSecondaryCommands);
[Fact]
public void IsOverflowButtonVisible_DefaultIsFalse()
=> Assert.False(new CommandBar().IsOverflowButtonVisible);
[Fact]
public void Content_DefaultIsNull()
=> Assert.Null(new CommandBar().Content);
[Fact]
public void PrimaryCommands_NotNull()
=> Assert.NotNull(new CommandBar().PrimaryCommands);
[Fact]
public void SecondaryCommands_NotNull()
=> Assert.NotNull(new CommandBar().SecondaryCommands);
[Fact]
public void VisiblePrimaryCommands_NotNull()
=> Assert.NotNull(new CommandBar().VisiblePrimaryCommands);
[Fact]
public void OverflowItems_NotNull()
=> Assert.NotNull(new CommandBar().OverflowItems);
[Fact]
public void PrimaryCommands_StartsEmpty()
=> Assert.Empty(new CommandBar().PrimaryCommands);
[Fact]
public void SecondaryCommands_StartsEmpty()
=> Assert.Empty(new CommandBar().SecondaryCommands);
[Fact]
public void PrimaryCommands_ReturnsNewListWhenNull()
{
var cb = new CommandBar();
cb.ClearValue(CommandBar.PrimaryCommandsProperty);
Assert.NotNull(cb.PrimaryCommands);
Assert.Empty(cb.PrimaryCommands);
}
[Fact]
public void SecondaryCommands_ReturnsNewListWhenNull()
{
var cb = new CommandBar();
cb.ClearValue(CommandBar.SecondaryCommandsProperty);
Assert.NotNull(cb.SecondaryCommands);
Assert.Empty(cb.SecondaryCommands);
}
[Fact]
public void VisiblePrimaryCommands_StartsEmpty()
=> Assert.Empty(new CommandBar().VisiblePrimaryCommands);
[Fact]
public void OverflowItems_StartsEmpty()
=> Assert.Empty(new CommandBar().OverflowItems);
[Fact]
public void ItemWidthBottom_DefaultIs70()
=> Assert.Equal(70d, new CommandBar().ItemWidthBottom);
[Fact]
public void ItemWidthRight_DefaultIs102()
=> Assert.Equal(102d, new CommandBar().ItemWidthRight);
[Fact]
public void ItemWidthCollapsed_DefaultIs42()
=> Assert.Equal(42d, new CommandBar().ItemWidthCollapsed);
}
public class CommandBarPropertyRoundTripTests : ScopedTestBase
{
[Fact]
public void Content_RoundTrip()
{
var cb = new CommandBar();
var content = new object();
cb.Content = content;
Assert.Same(content, cb.Content);
}
[Fact]
public void DefaultLabelPosition_RoundTrip()
{
var cb = new CommandBar { DefaultLabelPosition = CommandBarDefaultLabelPosition.Right };
Assert.Equal(CommandBarDefaultLabelPosition.Right, cb.DefaultLabelPosition);
}
[Fact]
public void IsOpen_RoundTrip()
{
var cb = new CommandBar { IsOpen = true };
Assert.True(cb.IsOpen);
cb.IsOpen = false;
Assert.False(cb.IsOpen);
}
[Fact]
public void IsSticky_RoundTrip()
{
var cb = new CommandBar { IsSticky = true };
Assert.True(cb.IsSticky);
}
[Fact]
public void IsDynamicOverflowEnabled_RoundTrip()
{
var cb = new CommandBar { IsDynamicOverflowEnabled = true };
Assert.True(cb.IsDynamicOverflowEnabled);
}
[Fact]
public void OverflowButtonVisibility_RoundTrip()
{
var cb = new CommandBar { OverflowButtonVisibility = CommandBarOverflowButtonVisibility.Visible };
Assert.Equal(CommandBarOverflowButtonVisibility.Visible, cb.OverflowButtonVisibility);
}
[Fact]
public void ItemWidthBottom_RoundTrip()
{
var cb = new CommandBar { ItemWidthBottom = 80d };
Assert.Equal(80d, cb.ItemWidthBottom);
}
[Fact]
public void ItemWidthRight_RoundTrip()
{
var cb = new CommandBar { ItemWidthRight = 120d };
Assert.Equal(120d, cb.ItemWidthRight);
}
[Fact]
public void ItemWidthCollapsed_RoundTrip()
{
var cb = new CommandBar { ItemWidthCollapsed = 50d };
Assert.Equal(50d, cb.ItemWidthCollapsed);
}
}
public class CommandBarIsOpenTests : ScopedTestBase
{
[Fact]
public void Opening_FiredWhenIsOpenBecomesTrue()
{
var cb = new CommandBar();
bool fired = false;
cb.Opening += (_, _) => fired = true;
cb.IsOpen = true;
Assert.True(fired);
}
[Fact]
public void Opened_FiredWhenIsOpenBecomesTrue()
{
var cb = new CommandBar();
bool fired = false;
cb.Opened += (_, _) => fired = true;
cb.IsOpen = true;
Assert.True(fired);
}
[Fact]
public void Closing_FiredWhenIsOpenBecomesFalse()
{
var cb = new CommandBar { IsOpen = true };
bool fired = false;
cb.Closing += (_, _) => fired = true;
cb.IsOpen = false;
Assert.True(fired);
}
[Fact]
public void Closed_FiredWhenIsOpenBecomesFalse()
{
var cb = new CommandBar { IsOpen = true };
bool fired = false;
cb.Closed += (_, _) => fired = true;
cb.IsOpen = false;
Assert.True(fired);
}
[Fact]
public void Opening_NotFiredWhenAlreadyOpen()
{
var cb = new CommandBar();
cb.IsOpen = true;
int count = 0;
cb.Opening += (_, _) => count++;
cb.IsOpen = true;
Assert.Equal(0, count);
}
[Fact]
public void Closing_NotFiredWhenAlreadyClosed()
{
var cb = new CommandBar();
int count = 0;
cb.Closing += (_, _) => count++;
cb.IsOpen = false;
Assert.Equal(0, count);
}
[Fact]
public void Events_FiredInOrder_OpenThenClose()
{
var cb = new CommandBar();
var events = new List<string>();
cb.Opening += (_, _) => events.Add("Opening");
cb.Opened += (_, _) => events.Add("Opened");
cb.Closing += (_, _) => events.Add("Closing");
cb.Closed += (_, _) => events.Add("Closed");
cb.IsOpen = true;
cb.IsOpen = false;
Assert.Equal(new[] { "Opening", "Opened", "Closing", "Closed" }, events);
}
}
public class CommandBarCollectionTests : ScopedTestBase
{
[Fact]
public void PrimaryCommands_Added_AppearInVisiblePrimary_WhenDynamicOverflowDisabled()
{
var cb = new CommandBar();
var btn = new CommandBarButton { Label = "Save" };
cb.PrimaryCommands!.Add(btn);
Assert.Contains(btn, cb.VisiblePrimaryCommands);
}
[Fact]
public void PrimaryCommands_DefaultCollection_DoesNotDuplicateVisiblePrimaryNotifications()
{
var cb = new CommandBar();
var notifications = 0;
((INotifyCollectionChanged)cb.VisiblePrimaryCommands).CollectionChanged += (_, _) => notifications++;
cb.PrimaryCommands!.Add(new CommandBarButton { Label = "Save" });
Assert.Equal(2, notifications);
}
[Fact]
public void PrimaryCommands_Removed_DisappearsFromVisiblePrimary()
{
var cb = new CommandBar();
var btn = new CommandBarButton { Label = "Save" };
cb.PrimaryCommands!.Add(btn);
cb.PrimaryCommands!.Remove(btn);
Assert.DoesNotContain(btn, cb.VisiblePrimaryCommands);
}
[Fact]
public void SecondaryCommands_Added_AppearInOverflowItems()
{
var cb = new CommandBar();
var btn = new CommandBarButton { Label = "Settings" };
cb.SecondaryCommands!.Add(btn);
Assert.Contains(btn, cb.OverflowItems);
}
[Fact]
public void SecondaryCommands_DefaultCollection_DoesNotDuplicateOverflowNotifications()
{
var cb = new CommandBar();
var notifications = 0;
((INotifyCollectionChanged)cb.OverflowItems).CollectionChanged += (_, _) => notifications++;
cb.SecondaryCommands!.Add(new CommandBarButton { Label = "Settings" });
Assert.Equal(2, notifications);
}
[Fact]
public void SecondaryCommands_Removed_DisappearsFromOverflowItems()
{
var cb = new CommandBar();
var btn = new CommandBarButton { Label = "Settings" };
cb.SecondaryCommands!.Add(btn);
cb.SecondaryCommands!.Remove(btn);
Assert.DoesNotContain(btn, cb.OverflowItems);
}
[Fact]
public void HasSecondaryCommands_TrueWhenSecondaryAdded()
{
var cb = new CommandBar();
cb.SecondaryCommands!.Add(new CommandBarButton { Label = "Options" });
Assert.True(cb.HasSecondaryCommands);
}
[Fact]
public void HasSecondaryCommands_FalseAfterSecondaryCleared()
{
var cb = new CommandBar();
var btn = new CommandBarButton { Label = "Options" };
cb.SecondaryCommands!.Add(btn);
cb.SecondaryCommands!.Remove(btn);
Assert.False(cb.HasSecondaryCommands);
}
[Fact]
public void OverflowItems_CountMatchesSecondaryCommandCount()
{
var cb = new CommandBar();
cb.SecondaryCommands!.Add(new CommandBarButton());
cb.SecondaryCommands!.Add(new CommandBarButton());
Assert.Equal(2, cb.OverflowItems.Count);
}
[Fact]
public void VisiblePrimaryCommands_CountMatchesPrimary_WhenDynamicOverflowDisabled()
{
var cb = new CommandBar();
cb.PrimaryCommands!.Add(new CommandBarButton());
cb.PrimaryCommands!.Add(new CommandBarButton());
Assert.Equal(2, cb.VisiblePrimaryCommands.Count);
}
[Fact]
public void MultiplePrimaryCommands_AllVisibleInOrder()
{
var cb = new CommandBar();
var btn1 = new CommandBarButton { Label = "A" };
var btn2 = new CommandBarButton { Label = "B" };
var btn3 = new CommandBarButton { Label = "C" };
cb.PrimaryCommands!.Add(btn1);
cb.PrimaryCommands!.Add(btn2);
cb.PrimaryCommands!.Add(btn3);
Assert.Equal(new ICommandBarElement[] { btn1, btn2, btn3 }, cb.VisiblePrimaryCommands);
}
[Fact]
public void CommandBarSeparator_CanBeAddedToPrimaryCommands()
{
var cb = new CommandBar();
var sep = new CommandBarSeparator();
cb.PrimaryCommands!.Add(sep);
Assert.Contains(sep, cb.VisiblePrimaryCommands);
}
[Fact]
public void CommandBarToggleButton_CanBeAddedToPrimaryCommands()
{
var cb = new CommandBar();
var toggle = new CommandBarToggleButton { Label = "Bold" };
cb.PrimaryCommands!.Add(toggle);
Assert.Contains(toggle, cb.VisiblePrimaryCommands);
}
}
public class CommandBarLabelPositionTests : ScopedTestBase
{
[Fact]
public void DefaultLabelPosition_Collapsed_SetsIsCompactOnExistingPrimaryButton()
{
var cb = new CommandBar();
var btn = new CommandBarButton();
cb.PrimaryCommands!.Add(btn);
cb.DefaultLabelPosition = CommandBarDefaultLabelPosition.Collapsed;
Assert.True(btn.IsCompact);
}
[Fact]
public void DefaultLabelPosition_Bottom_ClearsIsCompactOnPrimaryButton()
{
var cb = new CommandBar();
var btn = new CommandBarButton();
cb.PrimaryCommands!.Add(btn);
cb.DefaultLabelPosition = CommandBarDefaultLabelPosition.Collapsed;
cb.DefaultLabelPosition = CommandBarDefaultLabelPosition.Bottom;
Assert.False(btn.IsCompact);
}
[Fact]
public void DefaultLabelPosition_Right_SetsLabelPositionOnPrimaryButton()
{
var cb = new CommandBar();
var btn = new CommandBarButton();
cb.PrimaryCommands!.Add(btn);
cb.DefaultLabelPosition = CommandBarDefaultLabelPosition.Right;
Assert.Equal(CommandBarDefaultLabelPosition.Right, btn.LabelPosition);
}
[Fact]
public void DefaultLabelPosition_Collapsed_SetsLabelPositionOnPrimaryButton()
{
var cb = new CommandBar();
var btn = new CommandBarButton();
cb.PrimaryCommands!.Add(btn);
cb.DefaultLabelPosition = CommandBarDefaultLabelPosition.Collapsed;
Assert.Equal(CommandBarDefaultLabelPosition.Collapsed, btn.LabelPosition);
}
[Fact]
public void DefaultLabelPosition_Collapsed_PropagatesIsCompactToToggleButton()
{
var cb = new CommandBar();
var toggle = new CommandBarToggleButton();
cb.PrimaryCommands!.Add(toggle);
cb.DefaultLabelPosition = CommandBarDefaultLabelPosition.Collapsed;
Assert.True(toggle.IsCompact);
Assert.Equal(CommandBarDefaultLabelPosition.Collapsed, toggle.LabelPosition);
}
[Fact]
public void DefaultLabelPosition_Right_PropagatesLabelPositionToToggleButton()
{
var cb = new CommandBar();
var toggle = new CommandBarToggleButton();
cb.PrimaryCommands!.Add(toggle);
cb.DefaultLabelPosition = CommandBarDefaultLabelPosition.Right;
Assert.Equal(CommandBarDefaultLabelPosition.Right, toggle.LabelPosition);
}
[Fact]
public void DefaultLabelPosition_Collapsed_SetsIsCompactOnSeparator()
{
var cb = new CommandBar();
var sep = new CommandBarSeparator();
cb.PrimaryCommands!.Add(sep);
cb.DefaultLabelPosition = CommandBarDefaultLabelPosition.Collapsed;
Assert.True(sep.IsCompact);
}
[Fact]
public void NewPrimaryCommand_GetsCurrentLabelPosition_WhenAlreadyCollapsed()
{
var cb = new CommandBar { DefaultLabelPosition = CommandBarDefaultLabelPosition.Collapsed };
var btn = new CommandBarButton();
cb.PrimaryCommands!.Add(btn);
Assert.True(btn.IsCompact);
Assert.Equal(CommandBarDefaultLabelPosition.Collapsed, btn.LabelPosition);
}
[Fact]
public void NewPrimaryCommand_GetsCurrentLabelPosition_WhenRight()
{
var cb = new CommandBar { DefaultLabelPosition = CommandBarDefaultLabelPosition.Right };
var btn = new CommandBarButton();
cb.PrimaryCommands!.Add(btn);
Assert.Equal(CommandBarDefaultLabelPosition.Right, btn.LabelPosition);
}
[Fact]
public void DefaultLabelPosition_Collapsed_AppliesToSecondaryCommands()
{
var cb = new CommandBar();
var btn = new CommandBarButton();
cb.SecondaryCommands!.Add(btn);
cb.DefaultLabelPosition = CommandBarDefaultLabelPosition.Collapsed;
Assert.True(btn.IsCompact);
}
[Fact]
public void DefaultLabelPosition_DoesNotClearLabelText()
{
var cb = new CommandBar();
var btn = new CommandBarButton { Label = "Save" };
cb.PrimaryCommands!.Add(btn);
cb.DefaultLabelPosition = CommandBarDefaultLabelPosition.Collapsed;
Assert.Equal("Save", btn.Label);
}
}
public class CommandBarOverflowButtonTests : ScopedTestBase
{
[Fact]
public void OverflowButtonVisibility_Visible_SetsIsOverflowButtonVisibleTrue()
{
var cb = new CommandBar { OverflowButtonVisibility = CommandBarOverflowButtonVisibility.Visible };
Assert.True(cb.IsOverflowButtonVisible);
}
[Fact]
public void OverflowButtonVisibility_Collapsed_SetsIsOverflowButtonVisibleFalse()
{
var cb = new CommandBar { OverflowButtonVisibility = CommandBarOverflowButtonVisibility.Collapsed };
Assert.False(cb.IsOverflowButtonVisible);
}
[Fact]
public void OverflowButtonVisibility_Auto_TrueWhenHasSecondaryCommands()
{
var cb = new CommandBar();
cb.SecondaryCommands!.Add(new CommandBarButton());
Assert.True(cb.IsOverflowButtonVisible);
}
[Fact]
public void OverflowButtonVisibility_Auto_FalseWhenNoSecondaryCommands()
{
var cb = new CommandBar();
Assert.False(cb.IsOverflowButtonVisible);
}
[Fact]
public void OverflowButtonVisibility_Visible_RemainsTrueWithoutSecondary()
{
var cb = new CommandBar { OverflowButtonVisibility = CommandBarOverflowButtonVisibility.Visible };
Assert.True(cb.IsOverflowButtonVisible);
}
[Fact]
public void OverflowButtonVisibility_Collapsed_RemainsFalseEvenWithSecondary()
{
var cb = new CommandBar { OverflowButtonVisibility = CommandBarOverflowButtonVisibility.Collapsed };
cb.SecondaryCommands!.Add(new CommandBarButton());
Assert.False(cb.IsOverflowButtonVisible);
}
[Fact]
public void OverflowButtonVisibility_Auto_FalseAfterSecondaryRemoved()
{
var cb = new CommandBar();
var btn = new CommandBarButton();
cb.SecondaryCommands!.Add(btn);
Assert.True(cb.IsOverflowButtonVisible);
cb.SecondaryCommands!.Remove(btn);
Assert.False(cb.IsOverflowButtonVisible);
}
[Fact]
public void OverflowButtonVisibility_SwitchFromAutoToVisible_ShowsButtonImmediately()
{
var cb = new CommandBar();
Assert.False(cb.IsOverflowButtonVisible);
cb.OverflowButtonVisibility = CommandBarOverflowButtonVisibility.Visible;
Assert.True(cb.IsOverflowButtonVisible);
}
}
public class CommandBarItemWidthTests : ScopedTestBase
{
private static CommandBar CreateWithWidth(double width)
{
var cb = new CommandBar();
cb.Measure(new Size(width, double.PositiveInfinity));
return cb;
}
[Fact]
public void ItemWidthBottom_Controls_HowManyButtonsFit()
{
var cb = CreateWithWidth(300);
var secondary = new CommandBarButton();
cb.SecondaryCommands!.Add(secondary); // forces overflow button
for (int i = 0; i < 4; i++)
cb.PrimaryCommands!.Add(new CommandBarButton());
cb.IsDynamicOverflowEnabled = true;
Assert.Equal(3, cb.VisiblePrimaryCommands.Count);
Assert.Equal(3, cb.OverflowItems.Count);
Assert.IsType<CommandBarButton>(cb.OverflowItems[0]);
Assert.IsType<CommandBarSeparator>(cb.OverflowItems[1]);
Assert.Same(secondary, cb.OverflowItems[2]);
}
[Fact]
public void ItemWidthBottom_Reduced_AllowsMoreItemsToFit()
{
var cb = CreateWithWidth(300);
cb.ItemWidthBottom = 35;
cb.SecondaryCommands!.Add(new CommandBarButton());
for (int i = 0; i < 4; i++)
cb.PrimaryCommands!.Add(new CommandBarButton());
cb.IsDynamicOverflowEnabled = true;
Assert.Equal(4, cb.VisiblePrimaryCommands.Count);
}
[Fact]
public void ItemWidthBottom_Large_ReducesToMinimumOneVisible()
{
var cb = CreateWithWidth(300);
cb.ItemWidthBottom = 260;
cb.SecondaryCommands!.Add(new CommandBarButton());
for (int i = 0; i < 3; i++)
cb.PrimaryCommands!.Add(new CommandBarButton());
cb.IsDynamicOverflowEnabled = true;
Assert.Equal(1, cb.VisiblePrimaryCommands.Count);
}
[Fact]
public void ItemWidthRight_UsedWhenLabelPositionIsRight()
{
var cb = CreateWithWidth(300);
cb.DefaultLabelPosition = CommandBarDefaultLabelPosition.Right;
cb.SecondaryCommands!.Add(new CommandBarButton());
for (int i = 0; i < 4; i++)
cb.PrimaryCommands!.Add(new CommandBarButton());
cb.IsDynamicOverflowEnabled = true;
Assert.Equal(2, cb.VisiblePrimaryCommands.Count);
}
[Fact]
public void ItemWidthRight_Increased_FewerItemsFit()
{
var cb = CreateWithWidth(300);
cb.DefaultLabelPosition = CommandBarDefaultLabelPosition.Right;
cb.ItemWidthRight = 252; // exactly 1 fits: 252/252=1
cb.SecondaryCommands!.Add(new CommandBarButton());
for (int i = 0; i < 3; i++)
cb.PrimaryCommands!.Add(new CommandBarButton());
cb.IsDynamicOverflowEnabled = true;
Assert.Equal(1, cb.VisiblePrimaryCommands.Count);
}
[Fact]
public void ItemWidthCollapsed_UsedWhenLabelPositionIsCollapsed()
{
var cb = CreateWithWidth(300);
cb.DefaultLabelPosition = CommandBarDefaultLabelPosition.Collapsed;
cb.SecondaryCommands!.Add(new CommandBarButton());
for (int i = 0; i < 4; i++)
cb.PrimaryCommands!.Add(new CommandBarButton());
cb.IsDynamicOverflowEnabled = true;
Assert.Equal(4, cb.VisiblePrimaryCommands.Count);
}
[Fact]
public void ItemWidths_AreIndependent_PerLabelPosition()
{
var cb = CreateWithWidth(300);
cb.ItemWidthBottom = 70;
cb.ItemWidthRight = 102;
cb.ItemWidthCollapsed = 42;
cb.SecondaryCommands!.Add(new CommandBarButton());
for (int i = 0; i < 4; i++)
cb.PrimaryCommands!.Add(new CommandBarButton());
cb.DefaultLabelPosition = CommandBarDefaultLabelPosition.Bottom;
cb.IsDynamicOverflowEnabled = true;
int visibleBottom = cb.VisiblePrimaryCommands.Count; // 252/70 = 3
cb.IsDynamicOverflowEnabled = false;
cb.DefaultLabelPosition = CommandBarDefaultLabelPosition.Right;
cb.IsDynamicOverflowEnabled = true;
int visibleRight = cb.VisiblePrimaryCommands.Count; // 252/102 = 2
cb.IsDynamicOverflowEnabled = false;
cb.DefaultLabelPosition = CommandBarDefaultLabelPosition.Collapsed;
cb.IsDynamicOverflowEnabled = true;
int visibleCollapsed = cb.VisiblePrimaryCommands.Count; // 252/42 = 6 → capped at 4
Assert.Equal(3, visibleBottom);
Assert.Equal(2, visibleRight);
Assert.Equal(4, visibleCollapsed);
}
}
public class CommandBarOverflowKeyboardTests : ScopedTestBase
{
private readonly IDisposable _app;
public CommandBarOverflowKeyboardTests()
{
_app = UnitTestApplication.Start(TestServices.FocusableWindow);
}
public override void Dispose()
{
_app.Dispose();
base.Dispose();
}
[Fact]
public void Escape_WhenOverflowOpen_ClosesOverflow()
{
var cb = new CommandBar();
cb.SecondaryCommands.Add(new CommandBarButton { Label = "Action" });
var root = new TestRoot(useGlobalStyles: true, child: cb);
root.LayoutManager.ExecuteInitialLayoutPass();
cb.IsOpen = true;
RaiseKeyOnOverflowPresenter(cb, Key.Escape);
Assert.False(cb.IsOpen);
}
[Fact]
public void Escape_WhenOverflowClosed_DoesNothing()
{
var cb = new CommandBar();
cb.SecondaryCommands.Add(new CommandBarButton { Label = "Action" });
var root = new TestRoot(useGlobalStyles: true, child: cb);
root.LayoutManager.ExecuteInitialLayoutPass();
RaiseKeyOnOverflowPresenter(cb, Key.Escape);
Assert.False(cb.IsOpen);
}
[Theory]
[InlineData(Key.Down)]
[InlineData(Key.Up)]
[InlineData(Key.Home)]
[InlineData(Key.End)]
public void NavigationKeys_AreHandled_WhenOverflowHasItems(Key key)
{
var cb = new CommandBar();
cb.SecondaryCommands.Add(new CommandBarButton { Label = "A" });
cb.SecondaryCommands.Add(new CommandBarButton { Label = "B" });
var root = new TestRoot(useGlobalStyles: true, child: cb);
root.LayoutManager.ExecuteInitialLayoutPass();
cb.IsOpen = true;
var e = new KeyEventArgs { RoutedEvent = InputElement.KeyDownEvent, Key = key };
GetOverflowPresenter(cb).RaiseEvent(e);
Assert.True(e.Handled);
}
[Fact]
public void NavigationKeys_AreHandled_WhenAllItemsAreSeparators()
{
var cb = new CommandBar();
cb.SecondaryCommands.Add(new CommandBarSeparator());
var root = new TestRoot(useGlobalStyles: true, child: cb);
root.LayoutManager.ExecuteInitialLayoutPass();
cb.IsOpen = true;
var e = new KeyEventArgs { RoutedEvent = InputElement.KeyDownEvent, Key = Key.Down };
GetOverflowPresenter(cb).RaiseEvent(e);
Assert.True(e.Handled);
}
[Fact]
public void NavigationKeys_AreHandled_WhenAllItemsAreDisabled()
{
var cb = new CommandBar();
cb.SecondaryCommands.Add(new CommandBarButton { Label = "A", IsEnabled = false });
var root = new TestRoot(useGlobalStyles: true, child: cb);
root.LayoutManager.ExecuteInitialLayoutPass();
cb.IsOpen = true;
var e = new KeyEventArgs { RoutedEvent = InputElement.KeyDownEvent, Key = Key.Down };
GetOverflowPresenter(cb).RaiseEvent(e);
Assert.True(e.Handled);
}
[Fact]
public void NavigationKeys_AreHandled_WhenAllItemsAreNonFocusable()
{
var cb = new CommandBar();
cb.SecondaryCommands.Add(new CommandBarButton { Label = "A", Focusable = false });
var root = new TestRoot(useGlobalStyles: true, child: cb);
root.LayoutManager.ExecuteInitialLayoutPass();
cb.IsOpen = true;
var e = new KeyEventArgs { RoutedEvent = InputElement.KeyDownEvent, Key = Key.Down };
GetOverflowPresenter(cb).RaiseEvent(e);
Assert.True(e.Handled);
}
[Fact]
public void KeyboardOpen_FocusesFirstOverflowItem_AsFocusVisible()
{
var first = new CommandBarButton { Label = "A" };
var cb = new CommandBar();
cb.SecondaryCommands.Add(first);
var window = CreateWindow(cb);
Assert.True(GetOverflowButton(cb).Focus(NavigationMethod.Tab));
cb.IsOpen = true;
Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded, TestContext.Current.CancellationToken);
Assert.True(first.IsFocused);
Assert.True(first.Classes.Contains(":focus-visible"));
}
[Fact]
public void PointerOpen_AfterKeyboardFocus_DoesNotMakeFirstOverflowItemFocusVisible()
{
var first = new CommandBarButton { Label = "A" };
var cb = new CommandBar();
cb.SecondaryCommands.Add(first);
var window = CreateWindow(cb);
var overflowButton = GetOverflowButton(cb);
Assert.True(overflowButton.Focus(NavigationMethod.Tab));
RaisePointerPressed(overflowButton);
cb.IsOpen = true;
Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded, TestContext.Current.CancellationToken);
Assert.True(first.IsFocused);
Assert.False(first.Classes.Contains(":focus-visible"));
}
[Fact]
public void KeyboardOpen_AfterPointerFocus_MakesFirstOverflowItemFocusVisible()
{
var first = new CommandBarButton { Label = "A" };
var cb = new CommandBar();
cb.SecondaryCommands.Add(first);
var window = CreateWindow(cb);
var overflowButton = GetOverflowButton(cb);
Assert.True(overflowButton.Focus(NavigationMethod.Pointer));
overflowButton.RaiseEvent(new KeyEventArgs
{
RoutedEvent = InputElement.KeyDownEvent,
Key = Key.Space,
});
cb.IsOpen = true;
Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded, TestContext.Current.CancellationToken);
Assert.True(first.IsFocused);
Assert.True(first.Classes.Contains(":focus-visible"));
}
private static ItemsControl GetOverflowPresenter(CommandBar cb)
{
var popup = cb.GetVisualDescendants()
.OfType<Popup>()
.First(p => p.Name == "PART_OverflowPopup");
return popup.GetLogicalDescendants()
.OfType<ItemsControl>()
.First(x => x.Name == "PART_OverflowPresenter");
}
private static void RaiseKeyOnOverflowPresenter(CommandBar cb, Key key)
{
GetOverflowPresenter(cb).RaiseEvent(new KeyEventArgs
{
RoutedEvent = InputElement.KeyDownEvent,
Key = key,
});
}
private static Button GetOverflowButton(CommandBar cb)
{
return cb.GetVisualDescendants()
.OfType<Button>()
.First(x => x.Name == "PART_OverflowButton");
}
private static Window CreateWindow(Control content)
{
var window = new Window { Content = content };
window.Show();
window.ApplyStyling();
window.ApplyTemplate();
return window;
}
private static void RaisePointerPressed(Button target)
{
var pointer = new Pointer(Pointer.GetNextFreeId(), PointerType.Mouse, true);
target.RaiseEvent(new PointerPressedEventArgs(
target,
pointer,
target,
default,
timestamp: 1,
new PointerPointProperties(RawInputModifiers.LeftMouseButton, PointerUpdateKind.LeftButtonPressed),
KeyModifiers.None));
}
}
public class CommandBarSeparatorOverflowTests : ScopedTestBase
{
private static CommandBar CreateWithWidth(double width)
{
var cb = new CommandBar();
cb.Measure(new Size(width, double.PositiveInfinity));
return cb;
}
[Fact]
public void TrailingSeparator_IsNotLastVisibleItem()
{
// [Btn, Btn, Sep, Btn] with room for 2 buttons: Sep should NOT trail.
var cb = CreateWithWidth(300);
cb.SecondaryCommands!.Add(new CommandBarButton());
cb.PrimaryCommands!.Add(new CommandBarButton());
cb.PrimaryCommands.Add(new CommandBarButton());
cb.PrimaryCommands.Add(new CommandBarSeparator());
cb.PrimaryCommands.Add(new CommandBarButton());
cb.IsDynamicOverflowEnabled = true;
Assert.IsNotType<CommandBarSeparator>(cb.VisiblePrimaryCommands[^1]);
}
[Fact]
public void TrailingSeparator_MovedToOverflow()
{
// [Btn, Sep, Btn, Btn] with room for 1 button: Sep after the single visible button should overflow.
var cb = CreateWithWidth(300);
cb.ItemWidthBottom = 260;
cb.SecondaryCommands!.Add(new CommandBarButton());
cb.PrimaryCommands!.Add(new CommandBarButton());
cb.PrimaryCommands.Add(new CommandBarSeparator());
cb.PrimaryCommands.Add(new CommandBarButton());
cb.PrimaryCommands.Add(new CommandBarButton());
cb.IsDynamicOverflowEnabled = true;
Assert.Equal(1, cb.VisiblePrimaryCommands.Count);
Assert.IsType<CommandBarButton>(cb.VisiblePrimaryCommands[0]);
}
[Fact]
public void MultipleSeparators_AllTrailingOnesStripped()
{
// [Btn, Sep, Sep, Btn] with room for 1: both trailing separators should be stripped.
var cb = CreateWithWidth(300);
cb.ItemWidthBottom = 260;
cb.SecondaryCommands!.Add(new CommandBarButton());
cb.PrimaryCommands!.Add(new CommandBarButton());
cb.PrimaryCommands.Add(new CommandBarSeparator());
cb.PrimaryCommands.Add(new CommandBarSeparator());
cb.PrimaryCommands.Add(new CommandBarButton());
cb.IsDynamicOverflowEnabled = true;
Assert.Equal(1, cb.VisiblePrimaryCommands.Count);
Assert.IsType<CommandBarButton>(cb.VisiblePrimaryCommands[0]);
}
[Fact]
public void MidSeparator_StaysVisible_WhenButtonsOnBothSides()
{
// [Btn, Sep, Btn] with room for all: separator stays.
var cb = CreateWithWidth(300);
cb.PrimaryCommands!.Add(new CommandBarButton());
cb.PrimaryCommands.Add(new CommandBarSeparator());
cb.PrimaryCommands.Add(new CommandBarButton());
cb.IsDynamicOverflowEnabled = true;
Assert.Equal(3, cb.VisiblePrimaryCommands.Count);
Assert.IsType<CommandBarSeparator>(cb.VisiblePrimaryCommands[1]);
}
[Fact]
public void AllButtonsOverflow_SeparatorsAlsoOverflow()
{
// [Sep, Btn, Btn] with room for 0: everything overflows.
var cb = CreateWithWidth(50);
cb.SecondaryCommands!.Add(new CommandBarButton());
cb.PrimaryCommands!.Add(new CommandBarSeparator());
cb.PrimaryCommands.Add(new CommandBarButton());
cb.PrimaryCommands.Add(new CommandBarButton());
cb.IsDynamicOverflowEnabled = true;
Assert.Empty(cb.VisiblePrimaryCommands);
}
[Fact]
public void LeadingSeparator_IsStrippedFromVisible()
{
// [Sep, Btn, Btn, Btn] with room for 2: leading Sep should be stripped.
var cb = CreateWithWidth(300);
cb.SecondaryCommands!.Add(new CommandBarButton());
cb.PrimaryCommands!.Add(new CommandBarSeparator());
cb.PrimaryCommands.Add(new CommandBarButton());
cb.PrimaryCommands.Add(new CommandBarButton());
cb.PrimaryCommands.Add(new CommandBarButton());
cb.IsDynamicOverflowEnabled = true;
Assert.IsNotType<CommandBarSeparator>(cb.VisiblePrimaryCommands[0]);
}
[Fact]
public void ConsecutiveSeparators_CollapsedToOne()
{
// [Btn, Sep, Sep, Btn] all fit: only one separator should remain.
var cb = CreateWithWidth(300);
cb.PrimaryCommands!.Add(new CommandBarButton());
cb.PrimaryCommands.Add(new CommandBarSeparator());
cb.PrimaryCommands.Add(new CommandBarSeparator());
cb.PrimaryCommands.Add(new CommandBarButton());
cb.IsDynamicOverflowEnabled = true;
int sepCount = CountSeparators(cb.VisiblePrimaryCommands);
Assert.Equal(1, sepCount);
}
[Fact]
public void OrphanedMidSeparator_RemovedWhenNeighborOverflows()
{
// [Btn1, Sep, Btn2, Sep, Btn3] with room for 2: Btn3 overflows,
// second Sep becomes trailing and is removed. First Sep stays.
var cb = CreateWithWidth(300);
cb.ItemWidthBottom = 100;
cb.SecondaryCommands!.Add(new CommandBarButton());
cb.PrimaryCommands!.Add(new CommandBarButton());
cb.PrimaryCommands.Add(new CommandBarSeparator());
cb.PrimaryCommands.Add(new CommandBarButton());
cb.PrimaryCommands.Add(new CommandBarSeparator());
cb.PrimaryCommands.Add(new CommandBarButton());
cb.IsDynamicOverflowEnabled = true;
Assert.IsNotType<CommandBarSeparator>(cb.VisiblePrimaryCommands[^1]);
Assert.Equal(1, CountSeparators(cb.VisiblePrimaryCommands));
}
[Fact]
public void SeparatorBetweenOverflowedButtons_IsRemoved()
{
// [Btn1, Btn2, Sep, Btn3, Btn4] with room for 2: Btn3 and Btn4 overflow,
// Sep has no non-separator after it in visible set, so it is removed.
var cb = CreateWithWidth(300);
cb.ItemWidthBottom = 100;
cb.SecondaryCommands!.Add(new CommandBarButton());
cb.PrimaryCommands!.Add(new CommandBarButton());
cb.PrimaryCommands.Add(new CommandBarButton());
cb.PrimaryCommands.Add(new CommandBarSeparator());
cb.PrimaryCommands.Add(new CommandBarButton());
cb.PrimaryCommands.Add(new CommandBarButton());
cb.IsDynamicOverflowEnabled = true;
Assert.Equal(0, CountSeparators(cb.VisiblePrimaryCommands));
}
[Fact]
public void MultipleSeparatorGroups_OnlyValidOnesRemain()
{
// [Btn, Sep, Btn, Sep, Btn, Sep, Btn] with room for 3:
// last Btn overflows, last Sep becomes trailing, the rest stay.
var cb = CreateWithWidth(300);
cb.SecondaryCommands!.Add(new CommandBarButton());
cb.PrimaryCommands!.Add(new CommandBarButton());
cb.PrimaryCommands.Add(new CommandBarSeparator());
cb.PrimaryCommands.Add(new CommandBarButton());
cb.PrimaryCommands.Add(new CommandBarSeparator());
cb.PrimaryCommands.Add(new CommandBarButton());
cb.PrimaryCommands.Add(new CommandBarSeparator());
cb.PrimaryCommands.Add(new CommandBarButton());
cb.IsDynamicOverflowEnabled = true;
Assert.IsNotType<CommandBarSeparator>(cb.VisiblePrimaryCommands[^1]);
Assert.IsNotType<CommandBarSeparator>(cb.VisiblePrimaryCommands[0]);
}
[Fact]
public void OnlySeparators_AllOverflow()
{
// [Sep, Sep, Sep] with no buttons: all should overflow.
var cb = CreateWithWidth(300);
cb.SecondaryCommands!.Add(new CommandBarButton());
cb.PrimaryCommands!.Add(new CommandBarSeparator());
cb.PrimaryCommands.Add(new CommandBarSeparator());
cb.PrimaryCommands.Add(new CommandBarSeparator());
cb.IsDynamicOverflowEnabled = true;
Assert.Empty(cb.VisiblePrimaryCommands);
}
[Fact]
public void PrimarySeparator_IsRemovedInsteadOfBecomingFirstOverflowItem()
{
var cb = CreateWithWidth(300);
cb.ItemWidthBottom = 260;
var leadingSeparator = new CommandBarSeparator();
var firstButton = new CommandBarButton();
var overflowedButton = new CommandBarButton();
cb.PrimaryCommands!.Add(leadingSeparator);
cb.PrimaryCommands.Add(firstButton);
cb.PrimaryCommands.Add(overflowedButton);
cb.IsDynamicOverflowEnabled = true;
Assert.Single(cb.OverflowItems);
Assert.Same(overflowedButton, cb.OverflowItems[0]);
Assert.DoesNotContain(leadingSeparator, cb.OverflowItems);
}
[Fact]
public void OverflowedPrimaryCommands_PrecedeSecondaryCommands_WithSyntheticSeparator()
{
var cb = CreateWithWidth(300);
cb.ItemWidthBottom = 260;
var visiblePrimary = new CommandBarButton();
var originalPrimarySeparator = new CommandBarSeparator();
var overflowedPrimaryOne = new CommandBarButton();
var overflowedPrimaryTwo = new CommandBarButton();
var secondary = new CommandBarButton();
cb.PrimaryCommands!.Add(visiblePrimary);
cb.PrimaryCommands.Add(originalPrimarySeparator);
cb.PrimaryCommands.Add(overflowedPrimaryOne);
cb.PrimaryCommands.Add(overflowedPrimaryTwo);
cb.SecondaryCommands!.Add(secondary);
cb.IsDynamicOverflowEnabled = true;
Assert.Equal(4, cb.OverflowItems.Count);
Assert.Same(overflowedPrimaryOne, cb.OverflowItems[0]);
Assert.Same(overflowedPrimaryTwo, cb.OverflowItems[1]);
Assert.IsType<CommandBarSeparator>(cb.OverflowItems[2]);
Assert.NotSame(originalPrimarySeparator, cb.OverflowItems[2]);
Assert.Same(secondary, cb.OverflowItems[3]);
Assert.DoesNotContain(originalPrimarySeparator, cb.OverflowItems);
}
[Fact]
public void HiddenSecondaryCommands_DoNotGetSyntheticOverflowSeparator()
{
var cb = CreateWithWidth(300);
cb.ItemWidthBottom = 260;
var visiblePrimary = new CommandBarButton();
var overflowedPrimary = new CommandBarButton();
var hiddenSecondary = new CommandBarButton { IsVisible = false };
cb.PrimaryCommands!.Add(visiblePrimary);
cb.PrimaryCommands.Add(overflowedPrimary);
cb.SecondaryCommands!.Add(hiddenSecondary);
cb.IsDynamicOverflowEnabled = true;
Assert.Equal(2, cb.OverflowItems.Count);
Assert.Same(overflowedPrimary, cb.OverflowItems[0]);
Assert.Same(hiddenSecondary, cb.OverflowItems[1]);
Assert.DoesNotContain(cb.OverflowItems, x => x is CommandBarSeparator);
}
[Fact]
public void TogglingSecondaryVisibility_RebuildsSyntheticOverflowSeparator()
{
var cb = CreateWithWidth(300);
cb.ItemWidthBottom = 260;
var visiblePrimary = new CommandBarButton();
var overflowedPrimary = new CommandBarButton();
var secondary = new CommandBarButton();
cb.PrimaryCommands!.Add(visiblePrimary);
cb.PrimaryCommands.Add(overflowedPrimary);
cb.SecondaryCommands!.Add(secondary);
cb.IsDynamicOverflowEnabled = true;
Assert.Equal(3, cb.OverflowItems.Count);
Assert.Same(overflowedPrimary, cb.OverflowItems[0]);
Assert.IsType<CommandBarSeparator>(cb.OverflowItems[1]);
Assert.Same(secondary, cb.OverflowItems[2]);
secondary.IsVisible = false;
Assert.Equal(2, cb.OverflowItems.Count);
Assert.Same(overflowedPrimary, cb.OverflowItems[0]);
Assert.Same(secondary, cb.OverflowItems[1]);
Assert.DoesNotContain(cb.OverflowItems, x => x is CommandBarSeparator);
secondary.IsVisible = true;
Assert.Equal(3, cb.OverflowItems.Count);
Assert.Same(overflowedPrimary, cb.OverflowItems[0]);
Assert.IsType<CommandBarSeparator>(cb.OverflowItems[1]);
Assert.Same(secondary, cb.OverflowItems[2]);
}
private static int CountSeparators(IReadOnlyList<ICommandBarElement> items)
{
int count = 0;
for (var i = 0; i < items.Count; i++)
{
if (items[i] is CommandBarSeparator)
count++;
}
return count;
}
}
file sealed class DelegateCommand : System.Windows.Input.ICommand
{
private readonly System.Action<object?> _execute;
private readonly System.Func<object?, bool> _canExecute;
public DelegateCommand(System.Action<object?> execute, System.Func<object?, bool>? canExecute = null)
{
_execute = execute;
_canExecute = canExecute ?? (_ => true);
}
public event System.EventHandler? CanExecuteChanged { add { } remove { } }
public bool CanExecute(object? parameter) => _canExecute(parameter);
public void Execute(object? parameter) => _execute(parameter);
}