diff --git a/components/TabbedCommandBar/OpenSolution.bat b/components/TabbedCommandBar/OpenSolution.bat
new file mode 100644
index 00000000..814a56d4
--- /dev/null
+++ b/components/TabbedCommandBar/OpenSolution.bat
@@ -0,0 +1,3 @@
+@ECHO OFF
+
+powershell ..\..\tooling\ProjectHeads\GenerateSingleSampleHeads.ps1 -componentPath %CD% %*
\ No newline at end of file
diff --git a/components/TabbedCommandBar/samples/Assets/TabbedCommandBar.png b/components/TabbedCommandBar/samples/Assets/TabbedCommandBar.png
new file mode 100644
index 00000000..518ecb17
Binary files /dev/null and b/components/TabbedCommandBar/samples/Assets/TabbedCommandBar.png differ
diff --git a/components/TabbedCommandBar/samples/Dependencies.props b/components/TabbedCommandBar/samples/Dependencies.props
new file mode 100644
index 00000000..e622e1df
--- /dev/null
+++ b/components/TabbedCommandBar/samples/Dependencies.props
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/TabbedCommandBar/samples/TabbedCommandBar.Samples.csproj b/components/TabbedCommandBar/samples/TabbedCommandBar.Samples.csproj
new file mode 100644
index 00000000..986a3662
--- /dev/null
+++ b/components/TabbedCommandBar/samples/TabbedCommandBar.Samples.csproj
@@ -0,0 +1,21 @@
+
+
+ TabbedCommandBar
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+
+
+
+
diff --git a/components/TabbedCommandBar/samples/TabbedCommandBar.md b/components/TabbedCommandBar/samples/TabbedCommandBar.md
new file mode 100644
index 00000000..581440a3
--- /dev/null
+++ b/components/TabbedCommandBar/samples/TabbedCommandBar.md
@@ -0,0 +1,30 @@
+---
+title: TabbedCommandBar
+author: yoshiask
+description: A control for displaying multiple CommandBars in the same space, like Microsoft Office's ribbon.
+keywords: TabbedCommandBar, Control, Layout, commandbar, ribbon
+dev_langs:
+ - csharp
+category: Controls
+subcategory: Layout
+discussion-id: 0
+issue-id: 0
+icon: Assets/TabbedCommandBar.png
+---
+
+The [TabbedCommandBar](/dotnet/api/microsoft.toolkit.uwp.ui.controls.tabbedcommandbar) displays a set of [TabbedCommandBarItem](/dotnet/api/microsoft.toolkit.uwp.ui.controls.tabbedcommandbaritem) in a shared container found in many productivity type apps. It is based off of [NavigationView](/windows/uwp/design/controls-and-patterns/navigationview).
+
+`TabbedCommandBarItem` can be used to display certain items, and its `IsContextual` property can be set to change the default style into an item that is known from the Office apps to highlight to a user that certain context options are available.
+> [!Sample TabbedCommandBarSample]
+
+## Remarks
+
+The TabbedCommandBar automatically applies styles to known common controls inside an `AppBarElementContainer`. The following elements have styles:
+
+- ComboBox
+- SplitButton
+
+> [!NOTE]
+> The ComboBox does not allow changing its selection while it is in the overflow flyout.
+
+The `TabbedCommandBar` does not add any of its own properties. See [NavigationView](/uwp/api/windows.ui.xaml.controls.navigationview#properties) for a list of accessible properties.
diff --git a/components/TabbedCommandBar/samples/TabbedCommandBarSample.xaml b/components/TabbedCommandBar/samples/TabbedCommandBarSample.xaml
new file mode 100644
index 00000000..2b174253
--- /dev/null
+++ b/components/TabbedCommandBar/samples/TabbedCommandBarSample.xaml
@@ -0,0 +1,127 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/TabbedCommandBar/samples/TabbedCommandBarSample.xaml.cs b/components/TabbedCommandBar/samples/TabbedCommandBarSample.xaml.cs
new file mode 100644
index 00000000..bfe468ae
--- /dev/null
+++ b/components/TabbedCommandBar/samples/TabbedCommandBarSample.xaml.cs
@@ -0,0 +1,18 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using CommunityToolkit.WinUI.Controls;
+
+namespace TabbedCommandBarExperiment.Samples;
+
+[ToolkitSampleBoolOption("ContextualItem", true, Title = "Show contextual item")]
+
+[ToolkitSample(id: nameof(TabbedCommandBarSample), "TabbedCommandBar", description: $"A sample for showing how to create and use a {nameof(TabbedCommandBar)} control.")]
+public sealed partial class TabbedCommandBarSample : Page
+{
+ public TabbedCommandBarSample()
+ {
+ this.InitializeComponent();
+ }
+}
diff --git a/components/TabbedCommandBar/src/CommunityToolkit.WinUI.Controls.TabbedCommandBar.csproj b/components/TabbedCommandBar/src/CommunityToolkit.WinUI.Controls.TabbedCommandBar.csproj
new file mode 100644
index 00000000..b6829868
--- /dev/null
+++ b/components/TabbedCommandBar/src/CommunityToolkit.WinUI.Controls.TabbedCommandBar.csproj
@@ -0,0 +1,16 @@
+
+
+ TabbedCommandBar
+ This package contains TabbedCommandBar.
+
+
+ CommunityToolkit.WinUI.Controls.TabbedCommandBarRns
+
+
+
+
+
+
+ $(PackageIdPrefix).$(PackageIdVariant).Controls.$(ToolkitComponentName)
+
+
diff --git a/components/TabbedCommandBar/src/Dependencies.props b/components/TabbedCommandBar/src/Dependencies.props
new file mode 100644
index 00000000..e622e1df
--- /dev/null
+++ b/components/TabbedCommandBar/src/Dependencies.props
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/TabbedCommandBar/src/MultiTarget.props b/components/TabbedCommandBar/src/MultiTarget.props
new file mode 100644
index 00000000..b11c1942
--- /dev/null
+++ b/components/TabbedCommandBar/src/MultiTarget.props
@@ -0,0 +1,9 @@
+
+
+
+ uwp;wasdk;wpf;wasm;linuxgtk;macos;ios;android;
+
+
\ No newline at end of file
diff --git a/components/TabbedCommandBar/src/TabbedCommandBar.cs b/components/TabbedCommandBar/src/TabbedCommandBar.cs
new file mode 100644
index 00000000..dd638500
--- /dev/null
+++ b/components/TabbedCommandBar/src/TabbedCommandBar.cs
@@ -0,0 +1,107 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using NavigationView = Microsoft.UI.Xaml.Controls.NavigationView;
+using NavigationViewSelectionChangedEventArgs = Microsoft.UI.Xaml.Controls.NavigationViewSelectionChangedEventArgs;
+
+namespace CommunityToolkit.WinUI.Controls;
+
+///
+/// A basic TabbedCommandBar control that houses s
+///
+[ContentProperty(Name = nameof(MenuItems))]
+[TemplatePart(Name = "PART_TabbedCommandBarContent", Type = typeof(ContentControl))]
+[TemplatePart(Name = "PART_TabbedCommandBarContentBorder", Type = typeof(Border))]
+[TemplatePart(Name = "PART_TabChangedStoryboard", Type = typeof(Storyboard))]
+public partial class TabbedCommandBar : NavigationView
+{
+ private ContentControl? _tabbedCommandBarContent = null;
+ private Border? _tabbedCommandBarContentBorder = null;
+ private Storyboard? _tabChangedStoryboard = null;
+
+ ///
+ /// The last selected .
+ ///
+ private TabbedCommandBarItem? _previousSelectedItem = null;
+ private long _visibilityChangedToken;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public TabbedCommandBar()
+ {
+ DefaultStyleKey = typeof(TabbedCommandBar);
+ DefaultStyleResourceUri = new Uri("ms-appx:///CommunityToolkit.WinUI.Controls.TabbedCommandBar/Themes/Generic.xaml");
+
+ SelectionChanged += SelectedItemChanged;
+ Loaded += TabbedCommandBar_Loaded;
+ }
+
+ ///
+ protected override void OnApplyTemplate()
+ {
+ base.OnApplyTemplate();
+
+ if (_tabbedCommandBarContent != null)
+ {
+ _tabbedCommandBarContent.Content = null;
+ }
+
+ // Get TabbedCommandBarContent first, since setting SelectedItem requires it
+ _tabbedCommandBarContent = GetTemplateChild("PART_TabbedCommandBarContent") as ContentControl;
+ _tabbedCommandBarContentBorder = GetTemplateChild("PART_TabbedCommandBarContentBorder") as Border;
+ _tabChangedStoryboard = GetTemplateChild("TabChangedStoryboard") as Storyboard;
+
+ // TODO: We could maybe optimize and use a lower-level Loaded event for what's hosting the MenuItems
+ // to set SelectedItem, but then we may have to pull in another template part, so think we're OK
+ // to do the Loaded event at the top level.
+ }
+
+ private void TabbedCommandBar_Loaded(object sender, RoutedEventArgs e)
+ {
+ // We need to select the item after the template is realized, otherwise the SelectedItem's
+ // DataTemplate bindings don't properly navigate the visual tree.
+ SelectedItem = MenuItems.FirstOrDefault();
+ }
+
+ private void SelectedItemChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
+ {
+ var item = sender.SelectedItem as TabbedCommandBarItem;
+ if (item == null || item.Visibility == Visibility.Collapsed)
+ {
+ // If the item is now hidden, select the first item instead.
+ // I can't think of any way that the visibiltiy would be null
+ // and still be selectable, but let's handle it just in case.
+ sender.SelectedItem = sender.MenuItems.FirstOrDefault();
+ return;
+ }
+
+ // Remove the visibility PropertyChanged handler from the
+ // previously selected item
+ if (_previousSelectedItem != null)
+ {
+ _previousSelectedItem.UnregisterPropertyChangedCallback(TabbedCommandBarItem.VisibilityProperty, _visibilityChangedToken);
+ }
+
+ // Register a new visibility PropertyChangedcallback for the
+ // currently selected item
+ _previousSelectedItem = item;
+ _visibilityChangedToken =
+ _previousSelectedItem.RegisterPropertyChangedCallback(TabbedCommandBarItem.VisibilityProperty, SelectedItemVisibilityChanged);
+
+ // Set the TabbedCommandBar background and start the transition animation
+ _tabChangedStoryboard?.Begin();
+ }
+
+ private void SelectedItemVisibilityChanged(DependencyObject sender, DependencyProperty dp)
+ {
+ // If the item is not visible, default to the first tab
+ if (sender.GetValue(dp) is Visibility vis && vis == Visibility.Collapsed)
+ {
+ // FIXME: This will cause WinUI to throw an exception if run
+ // when the tabs overflow
+ SelectedItem = MenuItems.FirstOrDefault();
+ }
+ }
+}
diff --git a/components/TabbedCommandBar/src/TabbedCommandBar.xaml b/components/TabbedCommandBar/src/TabbedCommandBar.xaml
new file mode 100644
index 00000000..f80a262b
--- /dev/null
+++ b/components/TabbedCommandBar/src/TabbedCommandBar.xaml
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0,4
+ 4,0
+ 8
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/TabbedCommandBar/src/TabbedCommandBarItem.cs b/components/TabbedCommandBar/src/TabbedCommandBarItem.cs
new file mode 100644
index 00000000..19e45789
--- /dev/null
+++ b/components/TabbedCommandBar/src/TabbedCommandBarItem.cs
@@ -0,0 +1,123 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace CommunityToolkit.WinUI.Controls;
+
+///
+/// A to be displayed in a
+///
+[TemplatePart(Name = "PrimaryItemsControl", Type = typeof(ItemsControl))]
+[TemplatePart(Name = "MoreButton", Type = typeof(Button))]
+public partial class TabbedCommandBarItem : CommandBar
+{
+ private ItemsControl? _primaryItemsControl;
+ private Button? _moreButton;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public TabbedCommandBarItem()
+ {
+ DefaultStyleKey = typeof(TabbedCommandBarItem);
+ DefaultStyleResourceUri = new System.Uri("ms-appx:///CommunityToolkit.WinUI.Controls.TabbedCommandBar/Themes/Generic.xaml");
+ }
+
+ ///
+ /// Identifies the property.
+ ///
+ public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(
+ nameof(Header),
+ typeof(object),
+ typeof(TabbedCommandBarItem),
+ new PropertyMetadata(string.Empty));
+
+ ///
+ /// Gets or sets the text or to display in the header of this TabbedCommandBar tab.
+ ///
+ public object Header
+ {
+ get => (object)GetValue(HeaderProperty);
+ set => SetValue(HeaderProperty, value);
+ }
+
+ ///
+ /// Identifies the property.
+ ///
+ public static readonly DependencyProperty IsContextualProperty = DependencyProperty.Register(
+ nameof(IsContextual),
+ typeof(bool),
+ typeof(TabbedCommandBarItem),
+ new PropertyMetadata(false));
+
+ ///
+ /// Gets or sets a value indicating whether this tab is contextual.
+ ///
+ public bool IsContextual
+ {
+ get => (bool)GetValue(IsContextualProperty);
+ set => SetValue(IsContextualProperty, value);
+ }
+
+ ///
+ /// Identifies the property.
+ ///
+ public static readonly DependencyProperty OverflowButtonAlignmentProperty = DependencyProperty.Register(
+ nameof(OverflowButtonAlignment),
+ typeof(HorizontalAlignment),
+ typeof(TabbedCommandBarItem),
+ new PropertyMetadata(HorizontalAlignment.Left));
+
+ ///
+ /// Gets or sets a value indicating the alignment of the command overflow button.
+ ///
+ public HorizontalAlignment OverflowButtonAlignment
+ {
+ get => (HorizontalAlignment)GetValue(OverflowButtonAlignmentProperty);
+ set => SetValue(OverflowButtonAlignmentProperty, value);
+ }
+
+ ///
+ /// Identifies the property.
+ ///
+ public static readonly DependencyProperty CommandAlignmentProperty = DependencyProperty.Register(
+ nameof(CommandAlignment),
+ typeof(HorizontalAlignment),
+ typeof(TabbedCommandBarItem),
+ new PropertyMetadata(HorizontalAlignment.Stretch));
+
+ ///
+ /// Gets or sets a value indicating the alignment of the commands in the .
+ ///
+ public HorizontalAlignment CommandAlignment
+ {
+ get => (HorizontalAlignment)GetValue(CommandAlignmentProperty);
+ set => SetValue(CommandAlignmentProperty, value);
+ }
+
+ ///
+ protected override void OnApplyTemplate()
+ {
+ base.OnApplyTemplate();
+
+ _primaryItemsControl = GetTemplateChild("PrimaryItemsControl") as ItemsControl;
+ if (_primaryItemsControl != null)
+ {
+ _primaryItemsControl.HorizontalAlignment = CommandAlignment;
+ RegisterPropertyChangedCallback(CommandAlignmentProperty, (sender, dp) =>
+ {
+ _primaryItemsControl.HorizontalAlignment = (HorizontalAlignment)sender.GetValue(dp);
+ });
+ }
+
+ _moreButton = GetTemplateChild("MoreButton") as Button;
+ if (_moreButton != null)
+ {
+ _moreButton.HorizontalAlignment = OverflowButtonAlignment;
+ RegisterPropertyChangedCallback(OverflowButtonAlignmentProperty, (sender, dp) =>
+ {
+ _moreButton.HorizontalAlignment = (HorizontalAlignment)sender.GetValue(dp);
+ });
+ }
+ }
+}
diff --git a/components/TabbedCommandBar/src/TabbedCommandBarItem.xaml b/components/TabbedCommandBar/src/TabbedCommandBarItem.xaml
new file mode 100644
index 00000000..4f027b44
--- /dev/null
+++ b/components/TabbedCommandBar/src/TabbedCommandBarItem.xaml
@@ -0,0 +1,777 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/TabbedCommandBar/src/TabbedCommandBarItemTemplateSelector.cs b/components/TabbedCommandBar/src/TabbedCommandBarItemTemplateSelector.cs
new file mode 100644
index 00000000..bea08963
--- /dev/null
+++ b/components/TabbedCommandBar/src/TabbedCommandBarItemTemplateSelector.cs
@@ -0,0 +1,35 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace CommunityToolkit.WinUI.Controls;
+
+///
+/// used by for determining the style of normal vs. contextual s.
+///
+public class TabbedCommandBarItemTemplateSelector : DataTemplateSelector
+{
+ ///
+ /// Gets or sets the of a normal .
+ ///
+ public DataTemplate? Normal { get; set; }
+
+ ///
+ /// Gets or sets the of a contextual .
+ ///
+ public DataTemplate? Contextual { get; set; }
+
+ ///
+ protected override DataTemplate SelectTemplateCore(object item)
+ {
+#pragma warning disable CS8603 // Possible null reference return.
+ return item is TabbedCommandBarItem t && t.IsContextual ? Contextual : Normal;
+#pragma warning restore CS8603 // Possible null reference return.
+ }
+
+ ///
+ protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
+ {
+ return SelectTemplateCore(item);
+ }
+}
diff --git a/components/TabbedCommandBar/src/Themes/Generic.xaml b/components/TabbedCommandBar/src/Themes/Generic.xaml
new file mode 100644
index 00000000..7eda0386
--- /dev/null
+++ b/components/TabbedCommandBar/src/Themes/Generic.xaml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
diff --git a/components/TabbedCommandBar/tests/ExampleTabbedCommandBarTestClass.cs b/components/TabbedCommandBar/tests/ExampleTabbedCommandBarTestClass.cs
new file mode 100644
index 00000000..934f9eec
--- /dev/null
+++ b/components/TabbedCommandBar/tests/ExampleTabbedCommandBarTestClass.cs
@@ -0,0 +1,134 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using CommunityToolkit.Tooling.TestGen;
+using CommunityToolkit.Tests;
+using CommunityToolkit.WinUI.Controls;
+
+namespace TabbedCommandBarExperiment.Tests;
+
+[TestClass]
+public partial class ExampleTabbedCommandBarTestClass : VisualUITestBase
+{
+ // If you don't need access to UI objects directly or async code, use this pattern.
+ [TestMethod]
+ public void SimpleSynchronousExampleTest()
+ {
+ var assembly = typeof(TabbedCommandBar).Assembly;
+ var type = assembly.GetType(typeof(TabbedCommandBar).FullName ?? string.Empty);
+
+ Assert.IsNotNull(type, "Could not find TabbedCommandBar type.");
+ Assert.AreEqual(typeof(TabbedCommandBar), type, "Type of TabbedCommandBar does not match expected type.");
+ }
+
+ // If you don't need access to UI objects directly, use this pattern.
+ [TestMethod]
+ public async Task SimpleAsyncExampleTest()
+ {
+ await Task.Delay(250);
+
+ Assert.IsTrue(true);
+ }
+
+ // Example that shows how to check for exception throwing.
+ [TestMethod]
+ public void SimpleExceptionCheckTest()
+ {
+ // If you need to check exceptions occur for invalid inputs, etc...
+ // Use Assert.ThrowsException to limit the scope to where you expect the error to occur.
+ // Otherwise, using the ExpectedException attribute could swallow or
+ // catch other issues in setup code.
+ Assert.ThrowsException(() => throw new NotImplementedException());
+ }
+
+ // The UIThreadTestMethod automatically dispatches to the UI for us to work with UI objects.
+ [UIThreadTestMethod]
+ public void SimpleUIAttributeExampleTest()
+ {
+ var component = new TabbedCommandBar();
+ Assert.IsNotNull(component);
+ }
+
+ // The UIThreadTestMethod can also easily grab a XAML Page for us by passing its type as a parameter.
+ // This lets us actually test a control as it would behave within an actual application.
+ // The page will already be loaded by the time your test is called.
+ [UIThreadTestMethod]
+ public void SimpleUIExamplePageTest(ExampleTabbedCommandBarTestPage page)
+ {
+ // You can use the Toolkit Visual Tree helpers here to find the component by type or name:
+ var component = page.FindDescendant();
+
+ Assert.IsNotNull(component);
+
+ var componentByName = page.FindDescendant("TabbedCommandBarControl");
+
+ Assert.IsNotNull(componentByName);
+ }
+
+ // You can still do async work with a UIThreadTestMethod as well.
+ [UIThreadTestMethod]
+ public async Task SimpleAsyncUIExamplePageTest(ExampleTabbedCommandBarTestPage page)
+ {
+ // This helper can be used to wait for a rendering pass to complete.
+ // Note, this is already done by loading a Page with the [UIThreadTestMethod] helper.
+ await CompositionTargetHelper.ExecuteAfterCompositionRenderingAsync(() => { });
+
+ var component = page.FindDescendant();
+
+ Assert.IsNotNull(component);
+ }
+
+ //// ----------------------------- ADVANCED TEST SCENARIOS -----------------------------
+
+ // If you need to use DataRow, you can use this pattern with the UI dispatch still.
+ // Otherwise, checkout the UIThreadTestMethod attribute above.
+ // See https://github.com/CommunityToolkit/Labs-Windows/issues/186
+ [TestMethod]
+ public async Task ComplexAsyncUIExampleTest()
+ {
+ await EnqueueAsync(() =>
+ {
+ var component = new TabbedCommandBar();
+ Assert.IsNotNull(component);
+ });
+ }
+
+ // If you want to load other content not within a XAML page using the UIThreadTestMethod above.
+ // Then you can do that using the Load/UnloadTestContentAsync methods.
+ [TestMethod]
+ public async Task ComplexAsyncLoadUIExampleTest()
+ {
+ await EnqueueAsync(async () =>
+ {
+ var component = new TabbedCommandBar();
+ Assert.IsNotNull(component);
+ Assert.IsFalse(component.IsLoaded);
+
+ await LoadTestContentAsync(component);
+
+ Assert.IsTrue(component.IsLoaded);
+
+ await UnloadTestContentAsync(component);
+
+ Assert.IsFalse(component.IsLoaded);
+ });
+ }
+
+ // You can still use the UIThreadTestMethod to remove the extra layer for the dispatcher as well:
+ [UIThreadTestMethod]
+ public async Task ComplexAsyncLoadUIExampleWithoutDispatcherTest()
+ {
+ var component = new TabbedCommandBar();
+ Assert.IsNotNull(component);
+ Assert.IsFalse(component.IsLoaded);
+
+ await LoadTestContentAsync(component);
+
+ Assert.IsTrue(component.IsLoaded);
+
+ await UnloadTestContentAsync(component);
+
+ Assert.IsFalse(component.IsLoaded);
+ }
+}
diff --git a/components/TabbedCommandBar/tests/ExampleTabbedCommandBarTestPage.xaml b/components/TabbedCommandBar/tests/ExampleTabbedCommandBarTestPage.xaml
new file mode 100644
index 00000000..7936ebd5
--- /dev/null
+++ b/components/TabbedCommandBar/tests/ExampleTabbedCommandBarTestPage.xaml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
diff --git a/components/TabbedCommandBar/tests/ExampleTabbedCommandBarTestPage.xaml.cs b/components/TabbedCommandBar/tests/ExampleTabbedCommandBarTestPage.xaml.cs
new file mode 100644
index 00000000..4af6130a
--- /dev/null
+++ b/components/TabbedCommandBar/tests/ExampleTabbedCommandBarTestPage.xaml.cs
@@ -0,0 +1,16 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace TabbedCommandBarExperiment.Tests;
+
+///
+/// An empty page that can be used on its own or navigated to within a Frame.
+///
+public sealed partial class ExampleTabbedCommandBarTestPage : Page
+{
+ public ExampleTabbedCommandBarTestPage()
+ {
+ this.InitializeComponent();
+ }
+}
diff --git a/components/TabbedCommandBar/tests/TabbedCommandBar.Tests.projitems b/components/TabbedCommandBar/tests/TabbedCommandBar.Tests.projitems
new file mode 100644
index 00000000..c3a7b7eb
--- /dev/null
+++ b/components/TabbedCommandBar/tests/TabbedCommandBar.Tests.projitems
@@ -0,0 +1,23 @@
+
+
+
+ $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
+ true
+ 254FF722-89D0-4EEE-8DA3-BE527A57A16E
+
+
+ TabbedCommandBarExperiment.Tests
+
+
+
+
+ ExampleTabbedCommandBarTestPage.xaml
+
+
+
+
+ Designer
+ MSBuild:Compile
+
+
+
\ No newline at end of file
diff --git a/components/TabbedCommandBar/tests/TabbedCommandBar.Tests.shproj b/components/TabbedCommandBar/tests/TabbedCommandBar.Tests.shproj
new file mode 100644
index 00000000..eb9f6074
--- /dev/null
+++ b/components/TabbedCommandBar/tests/TabbedCommandBar.Tests.shproj
@@ -0,0 +1,13 @@
+
+
+
+ 254FF722-89D0-4EEE-8DA3-BE527A57A16E
+ 14.0
+
+
+
+
+
+
+
+