14
14
bool CommandBarFlyoutTrace::s_IsDebugOutputEnabled{ false };
15
15
bool CommandBarFlyoutTrace::s_IsVerboseDebugOutputEnabled{ false };
16
16
17
+ // List of AppBarButton dependency properties being listened to for raising the CommandBarFlyoutCommandBar::OnCommandBarElementDependencyPropertyChanged notifications.
18
+ // AppBarButton::IsCompact and AppBarButton::LabelPosition having no effect on an AppBarButton's rendering, when used as a secondary command, they are not present in the list.
19
+ winrt::DependencyProperty CommandBarFlyout::s_appBarButtonDependencyProperties[s_commandBarElementDependencyPropertiesCount]
20
+ {
21
+ winrt::AppBarButton::IconProperty (),
22
+ winrt::AppBarButton::LabelProperty (),
23
+ nullptr
24
+ };
25
+
26
+ // List of AppBarToggleButton dependency properties being listened to for raising the CommandBarFlyoutCommandBar::OnCommandBarElementDependencyPropertyChanged notifications.
27
+ // AppBarToggleButton::IsCompact and AppBarToggleButton::LabelPosition having no effect on an AppBarToggleButton's rendering, when used as a secondary command, they are not present in the list.
28
+ winrt::DependencyProperty CommandBarFlyout::s_appBarToggleButtonDependencyProperties[s_commandBarElementDependencyPropertiesCount]
29
+ {
30
+ winrt::AppBarToggleButton::IconProperty (),
31
+ winrt::AppBarToggleButton::LabelProperty (),
32
+ nullptr
33
+ };
34
+
17
35
CommandBarFlyout::CommandBarFlyout ()
18
36
{
19
37
__RP_Marker_ClassById (RuntimeProfiler::ProfId_CommandBarFlyout);
20
38
39
+ if (SharedHelpers::IsRS4OrHigher () && s_appBarButtonDependencyProperties[s_commandBarElementDependencyPropertiesCount - 1 ] == nullptr )
40
+ {
41
+ s_appBarButtonDependencyProperties[s_commandBarElementDependencyPropertiesCount - 1 ] = winrt::AppBarButton::KeyboardAcceleratorTextOverrideProperty ();
42
+ s_appBarToggleButtonDependencyProperties[s_commandBarElementDependencyPropertiesCount - 1 ] = winrt::AppBarToggleButton::KeyboardAcceleratorTextOverrideProperty ();
43
+ }
44
+
21
45
if (winrt::IFlyoutBase6 thisAsFlyoutBase6 = *this )
22
46
{
23
47
thisAsFlyoutBase6.ShouldConstrainToRootBounds (false );
@@ -65,6 +89,17 @@ CommandBarFlyout::CommandBarFlyout()
65
89
auto button = element.try_as <winrt::AppBarButton>();
66
90
auto toggleButton = element.try_as <winrt::AppBarToggleButton>();
67
91
92
+ UnhookCommandBarElementDependencyPropertyChanges (index );
93
+
94
+ if (button)
95
+ {
96
+ HookAppBarButtonDependencyPropertyChanges (button, index );
97
+ }
98
+ else if (toggleButton)
99
+ {
100
+ HookAppBarToggleButtonDependencyPropertyChanges (toggleButton, index );
101
+ }
102
+
68
103
if (button && !button.Flyout ())
69
104
{
70
105
m_secondaryButtonClickRevokerByIndexMap[index ] = button.Click (winrt::auto_revoke, closeFlyoutFunc);
@@ -91,6 +126,15 @@ CommandBarFlyout::CommandBarFlyout()
91
126
auto button = element.try_as <winrt::AppBarButton>();
92
127
auto toggleButton = element.try_as <winrt::AppBarToggleButton>();
93
128
129
+ if (button)
130
+ {
131
+ HookAppBarButtonDependencyPropertyChanges (button, index );
132
+ }
133
+ else if (toggleButton)
134
+ {
135
+ HookAppBarToggleButtonDependencyPropertyChanges (toggleButton, index );
136
+ }
137
+
94
138
if (button && !button.Flyout ())
95
139
{
96
140
m_secondaryButtonClickRevokerByIndexMap[index ] = button.Click (winrt::auto_revoke, closeFlyoutFunc);
@@ -103,12 +147,15 @@ CommandBarFlyout::CommandBarFlyout()
103
147
break ;
104
148
}
105
149
case winrt::CollectionChange::ItemRemoved:
150
+ UnhookCommandBarElementDependencyPropertyChanges (index );
151
+
106
152
SharedHelpers::EraseIfExists (m_secondaryButtonClickRevokerByIndexMap, index );
107
153
SharedHelpers::EraseIfExists (m_secondaryToggleButtonCheckedRevokerByIndexMap, index );
108
154
SharedHelpers::EraseIfExists (m_secondaryToggleButtonUncheckedRevokerByIndexMap, index );
109
155
break ;
110
156
case winrt::CollectionChange::Reset:
111
157
SetSecondaryCommandsToCloseWhenExecuted ();
158
+ HookAllCommandBarElementDependencyPropertyChanges ();
112
159
break ;
113
160
default :
114
161
MUX_ASSERT (false );
@@ -250,6 +297,8 @@ CommandBarFlyout::~CommandBarFlyout()
250
297
{
251
298
m_primaryCommands.VectorChanged (m_primaryCommandsVectorChangedToken);
252
299
m_secondaryCommands.VectorChanged (m_secondaryCommandsVectorChangedToken);
300
+
301
+ UnhookAllCommandBarElementDependencyPropertyChanges ();
253
302
}
254
303
255
304
winrt::IObservableVector<winrt::ICommandBarElement> CommandBarFlyout::PrimaryCommands ()
@@ -270,6 +319,7 @@ winrt::Control CommandBarFlyout::CreatePresenter()
270
319
SharedHelpers::CopyVector (m_secondaryCommands, commandBar->SecondaryCommands ());
271
320
272
321
SetSecondaryCommandsToCloseWhenExecuted ();
322
+ HookAllCommandBarElementDependencyPropertyChanges ();
273
323
274
324
winrt::FlyoutPresenter presenter;
275
325
presenter.Background (nullptr );
@@ -407,3 +457,89 @@ tracker_ref<winrt::FlyoutPresenter> CommandBarFlyout::GetPresenter()
407
457
{
408
458
return m_presenter;
409
459
}
460
+
461
+ void CommandBarFlyout::HookAppBarButtonDependencyPropertyChanges (winrt::AppBarButton const & appBarButton, int index)
462
+ {
463
+ const auto commandBarElementDependencyPropertiesCount = SharedHelpers::IsRS4OrHigher () ? s_commandBarElementDependencyPropertiesCount : s_commandBarElementDependencyPropertiesCountRS3;
464
+
465
+ for (int commandBarElementDependencyPropertyIndex = 0 ; commandBarElementDependencyPropertyIndex < commandBarElementDependencyPropertiesCount; commandBarElementDependencyPropertyIndex++)
466
+ {
467
+ m_propertyChangedRevokersByIndexMap[index ][commandBarElementDependencyPropertyIndex] =
468
+ RegisterPropertyChanged (
469
+ appBarButton,
470
+ s_appBarButtonDependencyProperties[commandBarElementDependencyPropertyIndex], { this , &CommandBarFlyout::OnCommandBarElementDependencyPropertyChanged });
471
+ }
472
+ }
473
+
474
+ void CommandBarFlyout::HookAppBarToggleButtonDependencyPropertyChanges (winrt::AppBarToggleButton const & appBarToggleButton, int index)
475
+ {
476
+ const auto commandBarElementDependencyPropertiesCount = SharedHelpers::IsRS4OrHigher () ? s_commandBarElementDependencyPropertiesCount : s_commandBarElementDependencyPropertiesCountRS3;
477
+
478
+ for (int commandBarElementDependencyPropertyIndex = 0 ; commandBarElementDependencyPropertyIndex < commandBarElementDependencyPropertiesCount; commandBarElementDependencyPropertyIndex++)
479
+ {
480
+ m_propertyChangedRevokersByIndexMap[index ][commandBarElementDependencyPropertyIndex] =
481
+ RegisterPropertyChanged (
482
+ appBarToggleButton,
483
+ s_appBarToggleButtonDependencyProperties[commandBarElementDependencyPropertyIndex], { this , &CommandBarFlyout::OnCommandBarElementDependencyPropertyChanged });
484
+ }
485
+ }
486
+
487
+ void CommandBarFlyout::HookAllCommandBarElementDependencyPropertyChanges ()
488
+ {
489
+ UnhookAllCommandBarElementDependencyPropertyChanges ();
490
+
491
+ for (uint32_t i = 0 ; i < SecondaryCommands ().Size (); i++)
492
+ {
493
+ auto element = SecondaryCommands ().GetAt (i);
494
+ auto button = element.try_as <winrt::AppBarButton>();
495
+ auto toggleButton = element.try_as <winrt::AppBarToggleButton>();
496
+
497
+ if (button)
498
+ {
499
+ HookAppBarButtonDependencyPropertyChanges (button, i);
500
+ }
501
+ else if (toggleButton)
502
+ {
503
+ HookAppBarToggleButtonDependencyPropertyChanges (toggleButton, i);
504
+ }
505
+ }
506
+ }
507
+
508
+ void CommandBarFlyout::UnhookCommandBarElementDependencyPropertyChanges (int index, bool eraseRevokers)
509
+ {
510
+ const auto revokers = m_propertyChangedRevokersByIndexMap.find (index );
511
+ if (revokers != m_propertyChangedRevokersByIndexMap.end ())
512
+ {
513
+ const auto commandBarElementDependencyPropertiesCount = SharedHelpers::IsRS4OrHigher () ? s_commandBarElementDependencyPropertiesCount : s_commandBarElementDependencyPropertiesCountRS3;
514
+
515
+ for (int commandBarElementDependencyPropertyIndex = 0 ; commandBarElementDependencyPropertyIndex < commandBarElementDependencyPropertiesCount; commandBarElementDependencyPropertyIndex++)
516
+ {
517
+ m_propertyChangedRevokersByIndexMap[index ][commandBarElementDependencyPropertyIndex].revoke ();
518
+ }
519
+
520
+ if (eraseRevokers)
521
+ {
522
+ m_propertyChangedRevokersByIndexMap.erase (revokers);
523
+ }
524
+ }
525
+ }
526
+
527
+ void CommandBarFlyout::UnhookAllCommandBarElementDependencyPropertyChanges ()
528
+ {
529
+ for (auto const & revokers : m_propertyChangedRevokersByIndexMap)
530
+ {
531
+ UnhookCommandBarElementDependencyPropertyChanges (revokers.first , false /* eraseRevokers*/ );
532
+ }
533
+ m_propertyChangedRevokersByIndexMap.clear ();
534
+ }
535
+
536
+ // Let the potential CommandBarFlyoutCommandBar know of the dependency property change so it can adjust its size.
537
+ void CommandBarFlyout::OnCommandBarElementDependencyPropertyChanged (winrt::DependencyObject const & dependencyObject, winrt::DependencyProperty const & dependencyProperty)
538
+ {
539
+ COMMANDBARFLYOUT_TRACE_VERBOSE (*this , TRACE_MSG_METH, METH_NAME, this );
540
+
541
+ if (auto commandBar = winrt::get_self<CommandBarFlyoutCommandBar>(m_commandBar.get ()))
542
+ {
543
+ commandBar->OnCommandBarElementDependencyPropertyChanged ();
544
+ }
545
+ }
0 commit comments