Skip to content

Commit 573e4a2

Browse files
authored
CommandBarFlyoutCommandBar fix - respond to size changes (#6868)
1 parent bf6a4d2 commit 573e4a2

File tree

6 files changed

+376
-18
lines changed

6 files changed

+376
-18
lines changed

dev/CommandBarFlyout/CommandBarFlyoutCommandBar.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -78,16 +78,20 @@ CommandBarFlyoutCommandBar::CommandBarFlyoutCommandBar()
7878
[this](auto const&, auto const&)
7979
{
8080
#ifdef _DEBUG
81-
COMMANDBARFLYOUT_TRACE_VERBOSE(*this, TRACE_MSG_METH_STR, METH_NAME, this, L"SizedChanged");
81+
COMMANDBARFLYOUT_TRACE_VERBOSE(*this, TRACE_MSG_METH_STR, METH_NAME, this, L"SizeChanged");
8282
#endif
8383

84-
UpdateUI(!m_commandBarFlyoutIsOpening);
84+
UpdateUI(!m_commandBarFlyoutIsOpening, true /*isForSizeChange*/);
8585
}
8686
});
8787

8888
Closing({
8989
[this](auto const&, auto const&)
9090
{
91+
#ifdef _DEBUG
92+
COMMANDBARFLYOUT_TRACE_VERBOSE(*this, TRACE_MSG_METH_STR, METH_NAME, this, L"Closing");
93+
#endif
94+
9195
if (auto owningFlyout = m_owningFlyout.get())
9296
{
9397
if (owningFlyout.AlwaysExpanded())
@@ -283,7 +287,7 @@ void CommandBarFlyoutCommandBar::AttachEventHandlers()
283287
#endif
284288

285289
m_secondaryItemsRootSized = true;
286-
UpdateUI(!m_commandBarFlyoutIsOpening);
290+
UpdateUI(!m_commandBarFlyoutIsOpening, true /*isForSizeChange*/);
287291
}
288292
});
289293

@@ -499,19 +503,19 @@ void CommandBarFlyoutCommandBar::UpdateFlowsFromAndFlowsTo()
499503
}
500504

501505
void CommandBarFlyoutCommandBar::UpdateUI(
502-
bool useTransitions, bool isForCommandBarElementDependencyPropertyChange)
506+
bool useTransitions, bool isForSizeChange)
503507
{
504-
COMMANDBARFLYOUT_TRACE_VERBOSE(*this, TRACE_MSG_METH_INT_INT, METH_NAME, this, useTransitions, isForCommandBarElementDependencyPropertyChange);
508+
COMMANDBARFLYOUT_TRACE_VERBOSE(*this, TRACE_MSG_METH_INT_INT, METH_NAME, this, useTransitions, isForSizeChange);
505509

506510
UpdateTemplateSettings();
507-
UpdateVisualState(useTransitions, isForCommandBarElementDependencyPropertyChange);
511+
UpdateVisualState(useTransitions, isForSizeChange);
508512

509513
UpdateProjectedShadow();
510514
}
511515

512516
void CommandBarFlyoutCommandBar::UpdateVisualState(
513517
bool useTransitions,
514-
bool isForCommandBarElementDependencyPropertyChange)
518+
bool isForSizeChange)
515519
{
516520
if (IsOpen())
517521
{
@@ -575,14 +579,14 @@ void CommandBarFlyoutCommandBar::UpdateVisualState(
575579
}
576580
}
577581

578-
if (isForCommandBarElementDependencyPropertyChange)
582+
if (isForSizeChange)
579583
{
580-
// UpdateVisualState is called as a result of a secondary command bar element dependency property change. This CommandBarFlyoutCommandBar is already open
584+
// UpdateVisualState is called as a result of a size change (for instance caused by a secondary command bar element dependency property change). This CommandBarFlyoutCommandBar is already open
581585
// and expanded. Jump to the Collapsed and back to ExpandedUp/ExpandedDown state to apply all refreshed CommandBarFlyoutCommandBarTemplateSettings values.
582586
winrt::VisualStateManager::GoToState(*this, L"Collapsed", false);
583587
}
584588

585-
winrt::VisualStateManager::GoToState(*this, shouldExpandUp ? L"ExpandedUp" : L"ExpandedDown", useTransitions && !isForCommandBarElementDependencyPropertyChange);
589+
winrt::VisualStateManager::GoToState(*this, shouldExpandUp ? L"ExpandedUp" : L"ExpandedDown", useTransitions && !isForSizeChange);
586590

587591
// Union of AvailableCommandsStates and ExpansionStates
588592
bool hasPrimaryCommands = (PrimaryCommands().Size() != 0);
@@ -1404,6 +1408,6 @@ void CommandBarFlyoutCommandBar::OnCommandBarElementDependencyPropertyChanged()
14041408
// Only refresh the UI when the CommandBarFlyoutCommandBar is already open since it will be refreshed anyways in the event it gets opened.
14051409
if (IsOpen())
14061410
{
1407-
UpdateUI(!m_commandBarFlyoutIsOpening, true /*isForCommandBarElementDependencyPropertyChange*/);
1411+
UpdateUI(!m_commandBarFlyoutIsOpening, true /*isForSizeChange*/);
14081412
}
14091413
}

dev/CommandBarFlyout/CommandBarFlyoutCommandBar.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ class CommandBarFlyoutCommandBar :
4949
void DetachEventHandlers();
5050

5151
void UpdateFlowsFromAndFlowsTo();
52-
void UpdateUI(bool useTransitions = true, bool isForCommandBarElementDependencyPropertyChange = false);
53-
void UpdateVisualState(bool useTransitions, bool isForCommandBarElementDependencyPropertyChange = false);
52+
void UpdateUI(bool useTransitions = true, bool isForSizeChange = false);
53+
void UpdateVisualState(bool useTransitions, bool isForSizeChange = false);
5454
void UpdateTemplateSettings();
5555
void EnsureAutomationSetCountAndPosition();
5656
void EnsureLocalizedControlTypes();

dev/CommandBarFlyout/InteractionTests/CommandBarFlyoutTests.cs

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,6 +1005,174 @@ public void VerifyDynamicSecondaryCommandLabel()
10051005
}
10061006
}
10071007

1008+
[TestMethod]
1009+
public void VerifyDynamicSecondaryCommandVisibility()
1010+
{
1011+
if (PlatformConfiguration.IsOSVersionLessThan(OSVersion.Redstone2))
1012+
{
1013+
Log.Warning("Test is disabled pre-RS2 because CommandBarFlyout is not supported pre-RS2");
1014+
return;
1015+
}
1016+
1017+
using (var setup = new CommandBarFlyoutTestSetupHelper())
1018+
{
1019+
Log.Comment("Retrieving FlyoutTarget6");
1020+
Button showCommandBarFlyoutButton = FindElement.ByName<Button>("Show CommandBarFlyout with no primary commands");
1021+
1022+
Log.Comment("Retrieving IsFlyoutOpenCheckBox");
1023+
ToggleButton isFlyoutOpenCheckBox = FindElement.ById<ToggleButton>("IsFlyoutOpenCheckBox");
1024+
1025+
Log.Comment("Retrieving UseSecondaryCommandDynamicVisibilityCheckBox");
1026+
ToggleButton useSecondaryCommandDynamicVisibilityCheckBox = FindElement.ById<ToggleButton>("UseSecondaryCommandDynamicVisibilityCheckBox");
1027+
1028+
Log.Comment("SecondaryCommandDynamicVisibilityChangedCheckBox");
1029+
ToggleButton secondaryCommandDynamicVisibilityChangedCheckBox = FindElement.ById<ToggleButton>("SecondaryCommandDynamicVisibilityChangedCheckBox");
1030+
1031+
Log.Comment("Retrieving DynamicVisibilityTimerIntervalTextBox");
1032+
Edit dynamicVisibilityTimerIntervalTextBox = new Edit(FindElement.ById("DynamicVisibilityTimerIntervalTextBox"));
1033+
1034+
Log.Comment("Retrieving DynamicVisibilityChangeCountTextBox");
1035+
Edit dynamicVisibilityChangeCountTextBox = new Edit(FindElement.ById("DynamicVisibilityChangeCountTextBox"));
1036+
1037+
Verify.AreEqual(ToggleState.Off, isFlyoutOpenCheckBox.ToggleState);
1038+
1039+
Log.Comment("Change the fifth command bar element's Visibility property asynchronously after the command bar is opened");
1040+
useSecondaryCommandDynamicVisibilityCheckBox.Check();
1041+
1042+
Log.Comment("Setting DynamicVisibilityTimerIntervalTextBox to 1s");
1043+
dynamicVisibilityTimerIntervalTextBox.SetValue("1000");
1044+
1045+
Log.Comment("Setting DynamicVisibilityChangeCountTextBox to 1 single change");
1046+
dynamicVisibilityChangeCountTextBox.SetValue("1");
1047+
Wait.ForIdle();
1048+
1049+
Verify.AreEqual(ToggleState.Off, secondaryCommandDynamicVisibilityChangedCheckBox.ToggleState);
1050+
1051+
Log.Comment("Invoking button 'Show CommandBarFlyout with no primary commands' to show the Flyout6 command bar.");
1052+
showCommandBarFlyoutButton.Invoke();
1053+
Wait.ForIdle();
1054+
Verify.AreEqual(ToggleState.On, isFlyoutOpenCheckBox.ToggleState);
1055+
1056+
FocusHelper.SetFocus(FindElement.ById("UndoButton6"));
1057+
1058+
Button undoButton6 = FindElement.ById<Button>("UndoButton6");
1059+
Verify.IsNotNull(undoButton6);
1060+
1061+
UIObject commandBarElementsContainer = undoButton6.Parent;
1062+
Verify.IsNotNull(commandBarElementsContainer);
1063+
1064+
Rectangle initialBoundingRectangle = commandBarElementsContainer.BoundingRectangle;
1065+
1066+
Log.Comment("Initial commandBarElementsContainer.BoundingRectangle.Width=" + initialBoundingRectangle.Width);
1067+
Log.Comment("Initial commandBarElementsContainer.BoundingRectangle.Height=" + initialBoundingRectangle.Height);
1068+
1069+
Verify.AreEqual(ToggleState.Off, secondaryCommandDynamicVisibilityChangedCheckBox.ToggleState);
1070+
1071+
Log.Comment("Waiting for SecondaryCommandDynamicVisibilityChangedCheckBox becoming checked indicating the asynchronous Visibility property change occurred");
1072+
secondaryCommandDynamicVisibilityChangedCheckBox.GetToggledWaiter().Wait();
1073+
Wait.ForIdle();
1074+
1075+
Rectangle finalBoundingRectangle = commandBarElementsContainer.BoundingRectangle;
1076+
1077+
Log.Comment("Final commandBarElementsContainer.BoundingRectangle.Width=" + finalBoundingRectangle.Width);
1078+
Log.Comment("Final commandBarElementsContainer.BoundingRectangle.Height=" + finalBoundingRectangle.Height);
1079+
1080+
Log.Comment("Hitting Escape key to close the command bar.");
1081+
KeyboardHelper.PressKey(Key.Escape);
1082+
Wait.ForIdle();
1083+
1084+
Verify.AreEqual(ToggleState.Off, isFlyoutOpenCheckBox.ToggleState);
1085+
1086+
Log.Comment("Verifying the command bar flyout width and height were increased to accommodate the new AppBarButton.");
1087+
Verify.IsGreaterThan(finalBoundingRectangle.Width, initialBoundingRectangle.Width);
1088+
Verify.IsGreaterThan(finalBoundingRectangle.Height, initialBoundingRectangle.Height);
1089+
}
1090+
}
1091+
1092+
[TestMethod]
1093+
public void VerifyDynamicOverflowContentRootWidth()
1094+
{
1095+
if (PlatformConfiguration.IsOSVersionLessThan(OSVersion.Redstone2))
1096+
{
1097+
Log.Warning("Test is disabled pre-RS2 because CommandBarFlyout is not supported pre-RS2");
1098+
return;
1099+
}
1100+
1101+
using (var setup = new CommandBarFlyoutTestSetupHelper())
1102+
{
1103+
Log.Comment("Retrieving FlyoutTarget6");
1104+
Button showCommandBarFlyoutButton = FindElement.ByName<Button>("Show CommandBarFlyout with no primary commands");
1105+
1106+
Log.Comment("Retrieving IsFlyoutOpenCheckBox");
1107+
ToggleButton isFlyoutOpenCheckBox = FindElement.ById<ToggleButton>("IsFlyoutOpenCheckBox");
1108+
1109+
Log.Comment("Retrieving UseOverflowContentRootDynamicWidthCheckBox");
1110+
ToggleButton useOverflowContentRootDynamicWidthCheckBox = FindElement.ById<ToggleButton>("UseOverflowContentRootDynamicWidthCheckBox");
1111+
1112+
Log.Comment("OverflowContentRootDynamicWidthChangedCheckBox");
1113+
ToggleButton overflowContentRootDynamicWidthChangedCheckBox = FindElement.ById<ToggleButton>("OverflowContentRootDynamicWidthChangedCheckBox");
1114+
1115+
Log.Comment("Retrieving DynamicWidthTimerIntervalTextBox");
1116+
Edit dynamicWidthTimerIntervalTextBox = new Edit(FindElement.ById("DynamicWidthTimerIntervalTextBox"));
1117+
1118+
Log.Comment("Retrieving DynamicWidthChangeCountTextBox");
1119+
Edit dynamicWidthChangeCountTextBox = new Edit(FindElement.ById("DynamicWidthChangeCountTextBox"));
1120+
1121+
Verify.AreEqual(ToggleState.Off, isFlyoutOpenCheckBox.ToggleState);
1122+
1123+
Log.Comment("Change the fifth command bar element's Visibility property asynchronously after the command bar is opened");
1124+
useOverflowContentRootDynamicWidthCheckBox.Check();
1125+
1126+
Log.Comment("Setting DynamicWidthTimerIntervalTextBox to 1s");
1127+
dynamicWidthTimerIntervalTextBox.SetValue("1000");
1128+
1129+
Log.Comment("Setting DynamicWidthChangeCountTextBox to 1 single change");
1130+
dynamicWidthChangeCountTextBox.SetValue("1");
1131+
Wait.ForIdle();
1132+
1133+
Verify.AreEqual(ToggleState.Off, overflowContentRootDynamicWidthChangedCheckBox.ToggleState);
1134+
1135+
Log.Comment("Invoking button 'Show CommandBarFlyout with no primary commands' to show the Flyout6 command bar.");
1136+
showCommandBarFlyoutButton.Invoke();
1137+
Wait.ForIdle();
1138+
Verify.AreEqual(ToggleState.On, isFlyoutOpenCheckBox.ToggleState);
1139+
1140+
FocusHelper.SetFocus(FindElement.ById("UndoButton6"));
1141+
1142+
Button undoButton6 = FindElement.ById<Button>("UndoButton6");
1143+
Verify.IsNotNull(undoButton6);
1144+
1145+
UIObject commandBarElementsContainer = undoButton6.Parent;
1146+
Verify.IsNotNull(commandBarElementsContainer);
1147+
1148+
Rectangle initialBoundingRectangle = commandBarElementsContainer.BoundingRectangle;
1149+
1150+
Log.Comment("Initial commandBarElementsContainer.BoundingRectangle.Width=" + initialBoundingRectangle.Width);
1151+
Log.Comment("Initial commandBarElementsContainer.BoundingRectangle.Height=" + initialBoundingRectangle.Height);
1152+
1153+
Verify.AreEqual(ToggleState.Off, overflowContentRootDynamicWidthChangedCheckBox.ToggleState);
1154+
1155+
Log.Comment("Waiting for OverflowContentRootDynamicWidthChangedCheckBox becoming checked indicating the asynchronous Visibility property change occurred");
1156+
overflowContentRootDynamicWidthChangedCheckBox.GetToggledWaiter().Wait();
1157+
Wait.ForIdle();
1158+
1159+
Rectangle finalBoundingRectangle = commandBarElementsContainer.BoundingRectangle;
1160+
1161+
Log.Comment("Final commandBarElementsContainer.BoundingRectangle.Width=" + finalBoundingRectangle.Width);
1162+
Log.Comment("Final commandBarElementsContainer.BoundingRectangle.Height=" + finalBoundingRectangle.Height);
1163+
1164+
Log.Comment("Hitting Escape key to close the command bar.");
1165+
KeyboardHelper.PressKey(Key.Escape);
1166+
Wait.ForIdle();
1167+
1168+
Verify.AreEqual(ToggleState.Off, isFlyoutOpenCheckBox.ToggleState);
1169+
1170+
Log.Comment("Verifying the command bar flyout width was increased to accommodate the OverflowContentRoot's larger Width.");
1171+
Verify.IsGreaterThan(finalBoundingRectangle.Width, initialBoundingRectangle.Width);
1172+
Verify.AreEqual(finalBoundingRectangle.Height, initialBoundingRectangle.Height);
1173+
}
1174+
}
1175+
10081176
[TestMethod]
10091177
public void VerifyIsFlyoutKeyboardAccessibleWithNoPrimaryCommands()
10101178
{

dev/CommandBarFlyout/TestUI/CommandBarFlyoutPage.xaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@
130130
<AppBarButton x:Name="UndoButton5" AutomationProperties.AutomationId="UndoButton5" Label="Undo" Icon="Undo" Click="OnElementClicked" />
131131
<AppBarButton x:Name="RedoButton5" AutomationProperties.AutomationId="RedoButton5" Label="Redo" Icon="Redo" Click="OnElementClicked" />
132132
<AppBarButton x:Name="SelectAllButton5" AutomationProperties.AutomationId="SelectAllButton5" Label="Select all" Click="OnElementClicked" />
133+
<AppBarButton x:Name="LongLabelButton5" AutomationProperties.AutomationId="LongLabelButton5" Label="AppBarButton with long label" Visibility="Collapsed" Click="OnElementClicked" />
133134
</muxc:CommandBarFlyout.SecondaryCommands>
134135
</muxc:CommandBarFlyout>
135136
<muxc:CommandBarFlyout Placement="Right" x:Name="Flyout6" AutomationProperties.AutomationId="Flyout6" Opened="OnFlyoutOpened" Closed="OnFlyoutClosed">
@@ -138,6 +139,7 @@
138139
<AppBarButton x:Name="RedoButton6" AutomationProperties.AutomationId="RedoButton6" Label="Redo" Icon="Redo" Click="OnElementClicked" />
139140
<AppBarButton x:Name="SelectAllButton6" AutomationProperties.AutomationId="SelectAllButton6" Label="Select all" Click="OnElementClicked" />
140141
<AppBarToggleButton x:Name="FavoriteToggleButton6" AutomationProperties.AutomationId="FavoriteToggleButton6" Label="Favorite" Icon="Favorite" Checked="OnElementChecked" Unchecked="OnElementUnchecked" />
142+
<AppBarButton x:Name="LongLabelButton6" AutomationProperties.AutomationId="LongLabelButton6" Label="AppBarButton with long label" Visibility="Collapsed" Click="OnElementClicked" />
141143
</muxc:CommandBarFlyout.SecondaryCommands>
142144
</muxc:CommandBarFlyout>
143145
<muxc:CommandBarFlyout Placement="Right" x:Name="Flyout7" AutomationProperties.AutomationId="Flyout7" Opened="OnFlyoutOpened" Closed="OnFlyoutClosed">
@@ -236,6 +238,22 @@
236238
<TextBlock Text="Change Count:" Margin="5,0,0,0" VerticalAlignment="Center"/>
237239
<TextBox x:Name="DynamicLabelChangeCountTextBox" Text="4" Margin="5,0,0,0" AutomationProperties.AutomationId="DynamicLabelChangeCountTextBox"/>
238240
</StackPanel>
241+
<StackPanel Orientation="Horizontal" Margin="10,0,10,2">
242+
<CheckBox x:Name="UseSecondaryCommandDynamicVisibilityCheckBox" Content="Use Secondary Command with Dynamic Visibility?" AutomationProperties.AutomationId="UseSecondaryCommandDynamicVisibilityCheckBox" />
243+
<CheckBox x:Name="SecondaryCommandDynamicVisibilityChangedCheckBox" Content="Visibility Changed?" AutomationProperties.AutomationId="SecondaryCommandDynamicVisibilityChangedCheckBox" Margin="5,0,0,0" />
244+
<TextBlock Text="Timer Interval (ms):" Margin="5,0,0,0" VerticalAlignment="Center"/>
245+
<TextBox x:Name="DynamicVisibilityTimerIntervalTextBox" Text="1500" Margin="5,0,0,0" AutomationProperties.AutomationId="DynamicVisibilityTimerIntervalTextBox"/>
246+
<TextBlock Text="Change Count:" Margin="5,0,0,0" VerticalAlignment="Center"/>
247+
<TextBox x:Name="DynamicVisibilityChangeCountTextBox" Text="4" Margin="5,0,0,0" AutomationProperties.AutomationId="DynamicVisibilityChangeCountTextBox"/>
248+
</StackPanel>
249+
<StackPanel Orientation="Horizontal" Margin="10,0,10,2">
250+
<CheckBox x:Name="UseOverflowContentRootDynamicWidthCheckBox" Content="Use OverflowContentRoot with Dynamic Width?" AutomationProperties.AutomationId="UseOverflowContentRootDynamicWidthCheckBox" />
251+
<CheckBox x:Name="OverflowContentRootDynamicWidthChangedCheckBox" Content="Width Changed?" AutomationProperties.AutomationId="OverflowContentRootDynamicWidthChangedCheckBox" Margin="5,0,0,0" />
252+
<TextBlock Text="Timer Interval (ms):" Margin="5,0,0,0" VerticalAlignment="Center"/>
253+
<TextBox x:Name="DynamicWidthTimerIntervalTextBox" Text="1500" Margin="5,0,0,0" AutomationProperties.AutomationId="DynamicWidthTimerIntervalTextBox"/>
254+
<TextBlock Text="Change Count:" Margin="5,0,0,0" VerticalAlignment="Center"/>
255+
<TextBox x:Name="DynamicWidthChangeCountTextBox" Text="4" Margin="5,0,0,0" AutomationProperties.AutomationId="DynamicWidthChangeCountTextBox"/>
256+
</StackPanel>
239257
<CheckBox x:Name="ClearSecondaryCommandsCheckBox" Content="Clear Secondary Commands Asynchronously?" AutomationProperties.AutomationId="ClearSecondaryCommandsCheckBox" Margin="10,0,10,2" />
240258
</StackPanel>
241259
</ScrollViewer>

0 commit comments

Comments
 (0)