Learn Universal Windows Programming Via Modern C++ (CommandBar Control)

Before reading this article, I highly recommend reading the previous parts of the series.

In this article, we are going to learn about CommandBar control in Modern C++.

CommandBar

The CommandBar control is a new control in Universal Windows programming. It is like a Toolbar control that has more features compared to the Toolbar control.

 

A CommandBar is divided into the following two main areas,

  1. Content
  2. Command Area

CommandArea

A Command Area has a collection of AppBarButton, AppBarToggleButton and AppBarSeparator buttons only. We can’t add any extra controls into the list, directly under the Command Area.

Note

All three controls are not necessary to be present in the CommandBar.

A Command Area is divided into the following two areas,

  1. Primary commands
  2. Secondary commands
Commands

Primary and secondary commands are a priority and non-priority area, the priority area is always visible to the users, a non-priority area is always hidden to the users. Whenever the user wants to interact with the secondary area, click the “…” menu visible to the UI.

Secondary commands

Secondary commands are non-priority areas, but once the user has clicked the secondary area, we make it visible until the user interacts with the CommandBar based on the context menu. Generally, if we click outside the menu area, the overflow menu automatically disappears.

 

Note

If there is no space to display primary controls , It will be automatically hidden and display in the secondary area.

ex - Adding primary and secondary buttons
  1. auto appBtnPlay = CreateAppBarButton(Symbol::Play, L"Play", 1);  
  2.         auto appBtnAccept = CreateAppBarButton(Symbol::Accept, L"Accept", 2);  
  3.   
  4.         CommandBar cmdBar;  
  5.         cmdBar.PrimaryCommands().Append(appBtnPlay);  
  6.         cmdBar.SecondaryCommands().Append(appBtnAccept);   
IsSticky
  • IsSticky: True, the menu will display until the click of any menu item in the CommandBar.
  • Is IsSticky: False, the menu will disappear, click anywhere outside the menu item (the default mode).

Note

IsSticky property can be set as overall the CommandBar properties, it applies to the primary Command Area.

Ex - Set Isopen property as true
  1. CommandBar cmdBar;  
  2. cmdBar.IsSticky(true); 

IsOpen

IsOpen is true, CommandBar is open (Primary and secondary commands details will be visible to the user); If it's false default behaviors are applying to the user


Ex - Set Isopen property as true
  1. CommandBar cmdBar;  
  2. cmdBar.IsOpen(true);   

Content

The Content area is like a container, we can place any control inside the content area.

The below sample code explains how to add the stackpanel in the CommandBar content area.
  1. CommandBar cmdBar;    
  2. StackPanel sPanel;    
  3. sPanel.Children().Append(txtHeader);    
  4. sPanel.Children().Append(txtStatus);    
  5.   
  6. cmdBar.Content(sPanel);   

DisplayMode

Initial or runtime, we can change the display mode of the CommandBar, the default mode is compact mode.

ClosedDisplayMode is a property to change the display mode of the CommandBar,

  • Compact- Display CommandBar with icon mode, text are hidden
  • Minimal- Display CommandBar, icon and text are hidden
  • Hidden- Complete CommandBar is hidden.
  • FlowDirection- We can change the content area from the left to the right using the FlowDirection property.
Ex - how to set the ClosedDisplayMode in Minimal mode
  1. CommandBar cmdBar;  
  2. cmdBar.ClosedDisplayMode(AppBarClosedDisplayMode::Minimal);  

Ex
 
The below sample explains how to implement the CommandBar and Handling the Primary and secondary command event handler
and display the message into the CommandBar content area.
  1. #include "pch.h"  
  2.   
  3. using namespace winrt;  
  4. using namespace Windows::ApplicationModel;  
  5. using namespace Windows::ApplicationModel::Activation;  
  6. using namespace Windows::Foundation;  
  7. using namespace Windows::UI;  
  8. using namespace Windows::UI::Xaml;  
  9. using namespace Windows::UI::Xaml::Controls;  
  10. using namespace Windows::UI::Xaml::Controls::Primitives;  
  11. using namespace Windows::UI::Xaml::Interop;  
  12. using namespace Windows::UI::Xaml::Media;  
  13. using namespace Windows::UI::Xaml::Navigation;  
  14. using namespace Windows::UI::Popups;  
  15. using namespace Windows::Storage;  
  16.   
  17. struct App :ApplicationT<App>  
  18. {  
  19. public:  
  20.     App()  
  21.     {  
  22.   
  23.     }  
  24.     virtual ~App() = default;  
  25.   
  26.     TextBlock txtStatus;  
  27.   
  28.     TextBlock CreateTextBlock(hstring text)  
  29.     {  
  30.         TextBlock txtBlock;  
  31.         txtBlock.Text(text);  
  32.         txtBlock.TextAlignment(TextAlignment::Left);  
  33.         txtBlock.FontSize(15);  
  34.         return txtBlock;  
  35.     }  
  36.   
  37.     AppBarButton CreateAppBarButton(Symbol icon, hstring text, int Idx)  
  38.     {  
  39.         AppBarButton appBtn;  
  40.         appBtn.Label(text);  
  41.         appBtn.Click({ this,&App::OnBtnClick });  
  42.         appBtn.Tag(PropertyValue::CreateInt32(Idx));  
  43.         auto sIcon = CreateSymbolIcon(icon);  
  44.         appBtn.Icon(sIcon);  
  45.         return appBtn;  
  46.   
  47.     }  
  48.   
  49.     void OnBtnClick(IInspectable const &sender, RoutedEventArgs const args)  
  50.     {  
  51.         Button btn = sender.as<Button>();  
  52.         IPropertyValue tagId = btn.Tag().as<IPropertyValue>();  
  53.         if (tagId.GetInt32() == 1)  
  54.         {  
  55.             txtStatus.Text(L"Primary Button has clicked");  
  56.         }  
  57.         else if (tagId.GetInt32() == 2)  
  58.         {  
  59.             txtStatus.Text(L"Secondary Button has clicked");  
  60.         }  
  61.     }  
  62.   
  63.     SymbolIcon CreateSymbolIcon(Symbol icon)  
  64.     {  
  65.         SymbolIcon sIcon;  
  66.         sIcon.Symbol(icon);  
  67.         return sIcon;  
  68.     }  
  69.   
  70.     void OnLaunched(LaunchActivatedEventArgs const&)  
  71.     {  
  72.   
  73.         auto appBtnPlay = CreateAppBarButton(Symbol::Play, L"Play", 1);  
  74.         auto appBtnAccept = CreateAppBarButton(Symbol::Accept, L"Accept", 2);  
  75.   
  76.         CommandBar cmdBar;  
  77.         cmdBar.PrimaryCommands().Append(appBtnPlay);  
  78.         cmdBar.SecondaryCommands().Append(appBtnAccept);  
  79.   
  80.         auto txtHeader = CreateTextBlock(L"CommandBar content Area , Add custom controls here");  
  81.         txtHeader.FontSize(25);  
  82.   
  83.         StackPanel sPanel;  
  84.         sPanel.Children().Append(txtHeader);  
  85.         sPanel.Children().Append(txtStatus);  
  86.   
  87.         cmdBar.Content(sPanel);  
  88.   
  89.         cmdBar.Background(SolidColorBrush(Colors::BurlyWood()));  
  90.   
  91.         cmdBar.IsSticky(true);  
  92.         cmdBar.IsOpen(true);  
  93.   
  94.         //cmdBar.ClosedDisplayMode(AppBarClosedDisplayMode::Minimal);  
  95.           
  96.         Window window = Window::Current();  
  97.         window.Content(cmdBar);  
  98.         window.Activate();  
  99.   
  100.   
  101.     }  
  102. };  
  103.   
  104.   
  105.   
  106. int __stdcall wWinMain(HINSTANCEHINSTANCEPWSTRint)  
  107. {  
  108.     Application::Start([](auto &&) {make<App>(); });  
  109.     return 0;  

output
 
User clicks the primary button, the status is updated into the command bar content area.
 

Conclusion

I hope you understood how to use the CommandBar control.