From 42371ba0ab2c40d9848b40e3e4f2c66bfb1fe6b8 Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Mon, 25 Sep 2023 17:30:20 +0200 Subject: [PATCH 1/9] Init --- components/TabbedCommandBar/OpenSolution.bat | 3 + .../TabbedCommandBar/samples/Assets/icon.png | Bin 0 -> 6192 bytes .../samples/Dependencies.props | 31 ++ .../samples/TabbedCommandBar.Samples.csproj | 8 + .../samples/TabbedCommandBar.md | 32 ++ .../samples/TabbedCommandBarCustomSample.xaml | 200 ++++++++ .../TabbedCommandBarCustomSample.xaml.cs | 30 ++ ...kit.WinUI.Controls.TabbedCommandBar.csproj | 12 + .../TabbedCommandBar/src/Dependencies.props | 31 ++ .../TabbedCommandBar/src/MultiTarget.props | 9 + .../TabbedCommandBar/src/TabbedCommandBar.cs | 107 +++++ .../src/TabbedCommandBar.xaml | 339 ++++++++++++++ .../src/TabbedCommandBarItem.cs | 123 +++++ .../src/TabbedCommandBarItem.xaml | 428 ++++++++++++++++++ .../TabbedCommandBarItemTemplateSelector.cs | 35 ++ .../TabbedCommandBar/src/Themes/Generic.xaml | 10 + .../tests/ExampleTabbedCommandBarTestClass.cs | 134 ++++++ .../ExampleTabbedCommandBarTestPage.xaml | 14 + .../ExampleTabbedCommandBarTestPage.xaml.cs | 16 + .../tests/TabbedCommandBar.Tests.projitems | 23 + .../tests/TabbedCommandBar.Tests.shproj | 13 + 21 files changed, 1598 insertions(+) create mode 100644 components/TabbedCommandBar/OpenSolution.bat create mode 100644 components/TabbedCommandBar/samples/Assets/icon.png create mode 100644 components/TabbedCommandBar/samples/Dependencies.props create mode 100644 components/TabbedCommandBar/samples/TabbedCommandBar.Samples.csproj create mode 100644 components/TabbedCommandBar/samples/TabbedCommandBar.md create mode 100644 components/TabbedCommandBar/samples/TabbedCommandBarCustomSample.xaml create mode 100644 components/TabbedCommandBar/samples/TabbedCommandBarCustomSample.xaml.cs create mode 100644 components/TabbedCommandBar/src/CommunityToolkit.WinUI.Controls.TabbedCommandBar.csproj create mode 100644 components/TabbedCommandBar/src/Dependencies.props create mode 100644 components/TabbedCommandBar/src/MultiTarget.props create mode 100644 components/TabbedCommandBar/src/TabbedCommandBar.cs create mode 100644 components/TabbedCommandBar/src/TabbedCommandBar.xaml create mode 100644 components/TabbedCommandBar/src/TabbedCommandBarItem.cs create mode 100644 components/TabbedCommandBar/src/TabbedCommandBarItem.xaml create mode 100644 components/TabbedCommandBar/src/TabbedCommandBarItemTemplateSelector.cs create mode 100644 components/TabbedCommandBar/src/Themes/Generic.xaml create mode 100644 components/TabbedCommandBar/tests/ExampleTabbedCommandBarTestClass.cs create mode 100644 components/TabbedCommandBar/tests/ExampleTabbedCommandBarTestPage.xaml create mode 100644 components/TabbedCommandBar/tests/ExampleTabbedCommandBarTestPage.xaml.cs create mode 100644 components/TabbedCommandBar/tests/TabbedCommandBar.Tests.projitems create mode 100644 components/TabbedCommandBar/tests/TabbedCommandBar.Tests.shproj 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/icon.png b/components/TabbedCommandBar/samples/Assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5f574ceca233597ecc5d775fd2f516c0d9685cfa GIT binary patch literal 6192 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 O0000 + + + + + + + + + + + + + + + + + + + + + diff --git a/components/TabbedCommandBar/samples/TabbedCommandBar.Samples.csproj b/components/TabbedCommandBar/samples/TabbedCommandBar.Samples.csproj new file mode 100644 index 00000000..3bcf0c8a --- /dev/null +++ b/components/TabbedCommandBar/samples/TabbedCommandBar.Samples.csproj @@ -0,0 +1,8 @@ + + + TabbedCommandBar + + + + + diff --git a/components/TabbedCommandBar/samples/TabbedCommandBar.md b/components/TabbedCommandBar/samples/TabbedCommandBar.md new file mode 100644 index 00000000..c4add517 --- /dev/null +++ b/components/TabbedCommandBar/samples/TabbedCommandBar.md @@ -0,0 +1,32 @@ +--- +title: TabbedCommandBar +author: githubaccount +description: TODO: Your experiment's description here +keywords: TabbedCommandBar, Control, Layout +dev_langs: + - csharp +category: Controls +subcategory: Layout +discussion-id: 0 +issue-id: 0 +icon: assets/icon.png +--- + + + + + + + + + +# TabbedCommandBar + +TODO: Fill in information about this experiment and how to get started here... + +## Custom Control + +You can inherit from an existing component as well, like `Panel`, this example shows a control without a +XAML Style that will be more light-weight to consume by an app developer: + +> [!Sample TabbedCommandBarCustomSample] diff --git a/components/TabbedCommandBar/samples/TabbedCommandBarCustomSample.xaml b/components/TabbedCommandBar/samples/TabbedCommandBarCustomSample.xaml new file mode 100644 index 00000000..87e6063b --- /dev/null +++ b/components/TabbedCommandBar/samples/TabbedCommandBarCustomSample.xaml @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/TabbedCommandBar/samples/TabbedCommandBarCustomSample.xaml.cs b/components/TabbedCommandBar/samples/TabbedCommandBarCustomSample.xaml.cs new file mode 100644 index 00000000..60cc4d62 --- /dev/null +++ b/components/TabbedCommandBar/samples/TabbedCommandBarCustomSample.xaml.cs @@ -0,0 +1,30 @@ +// 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; + +/// +/// An example sample page of a custom control inheriting from Panel. +/// +[ToolkitSampleTextOption("TitleText", "This is a title", Title = "Input the text")] +[ToolkitSampleMultiChoiceOption("LayoutOrientation", "Horizontal", "Vertical", Title = "Orientation")] + +[ToolkitSample(id: nameof(TabbedCommandBarCustomSample), "Custom control", description: $"A sample for showing how to create and use a {nameof(TabbedCommandBar)} custom control.")] +public sealed partial class TabbedCommandBarCustomSample : Page +{ + public TabbedCommandBarCustomSample() + { + this.InitializeComponent(); + } + + // TODO: See https://github.com/CommunityToolkit/Labs-Windows/issues/149 + public static Orientation ConvertStringToOrientation(string orientation) => orientation switch + { + "Vertical" => Orientation.Vertical, + "Horizontal" => Orientation.Horizontal, + _ => throw new System.NotImplementedException(), + }; +} 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..00e5a6b7 --- /dev/null +++ b/components/TabbedCommandBar/src/CommunityToolkit.WinUI.Controls.TabbedCommandBar.csproj @@ -0,0 +1,12 @@ + + + TabbedCommandBar + This package contains TabbedCommandBar. + + + CommunityToolkit.WinUI.Controls.TabbedCommandBarRns + + + + + 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..1077dba1 --- /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 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..8f6bbc65 --- /dev/null +++ b/components/TabbedCommandBar/src/TabbedCommandBar.xaml @@ -0,0 +1,339 @@ + + + + + + + + 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..c929a3b6 --- /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 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..734d70c3 --- /dev/null +++ b/components/TabbedCommandBar/src/TabbedCommandBarItem.xaml @@ -0,0 +1,428 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..6f6172ea --- /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..4f009a7a --- /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 + + + + + + + + From 6b4c159b6fdf864e243182bb70bb38eaa76641df Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Tue, 26 Sep 2023 17:46:37 +0200 Subject: [PATCH 2/9] Improve styling and sample --- .../samples/Assets/TabbedCommandBar.png | Bin 0 -> 2695 bytes .../samples/TabbedCommandBar.Samples.csproj | 13 + .../samples/TabbedCommandBar.md | 30 +- .../samples/TabbedCommandBarCustomSample.xaml | 200 -------- .../TabbedCommandBarCustomSample.xaml.cs | 30 -- .../samples/TabbedCommandBarSample.xaml | 103 ++++ .../samples/TabbedCommandBarSample.xaml.cs | 18 + .../src/TabbedCommandBar.xaml | 30 +- .../src/TabbedCommandBarItem.xaml | 442 ++++++++++++++++-- 9 files changed, 563 insertions(+), 303 deletions(-) create mode 100644 components/TabbedCommandBar/samples/Assets/TabbedCommandBar.png delete mode 100644 components/TabbedCommandBar/samples/TabbedCommandBarCustomSample.xaml delete mode 100644 components/TabbedCommandBar/samples/TabbedCommandBarCustomSample.xaml.cs create mode 100644 components/TabbedCommandBar/samples/TabbedCommandBarSample.xaml create mode 100644 components/TabbedCommandBar/samples/TabbedCommandBarSample.xaml.cs diff --git a/components/TabbedCommandBar/samples/Assets/TabbedCommandBar.png b/components/TabbedCommandBar/samples/Assets/TabbedCommandBar.png new file mode 100644 index 0000000000000000000000000000000000000000..518ecb17f0827b69b2accf4416af5875dc92e7c1 GIT binary patch literal 2695 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 BAZGvo literal 0 HcmV?d00001 diff --git a/components/TabbedCommandBar/samples/TabbedCommandBar.Samples.csproj b/components/TabbedCommandBar/samples/TabbedCommandBar.Samples.csproj index 3bcf0c8a..986a3662 100644 --- a/components/TabbedCommandBar/samples/TabbedCommandBar.Samples.csproj +++ b/components/TabbedCommandBar/samples/TabbedCommandBar.Samples.csproj @@ -3,6 +3,19 @@ TabbedCommandBar + + + + + + + + + + PreserveNewest + + + diff --git a/components/TabbedCommandBar/samples/TabbedCommandBar.md b/components/TabbedCommandBar/samples/TabbedCommandBar.md index c4add517..581440a3 100644 --- a/components/TabbedCommandBar/samples/TabbedCommandBar.md +++ b/components/TabbedCommandBar/samples/TabbedCommandBar.md @@ -1,32 +1,30 @@ --- title: TabbedCommandBar -author: githubaccount -description: TODO: Your experiment's description here -keywords: TabbedCommandBar, Control, Layout +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/icon.png +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] -# TabbedCommandBar +## Remarks -TODO: Fill in information about this experiment and how to get started here... +The TabbedCommandBar automatically applies styles to known common controls inside an `AppBarElementContainer`. The following elements have styles: -## Custom Control +- ComboBox +- SplitButton -You can inherit from an existing component as well, like `Panel`, this example shows a control without a -XAML Style that will be more light-weight to consume by an app developer: +> [!NOTE] +> The ComboBox does not allow changing its selection while it is in the overflow flyout. -> [!Sample TabbedCommandBarCustomSample] +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/TabbedCommandBarCustomSample.xaml b/components/TabbedCommandBar/samples/TabbedCommandBarCustomSample.xaml deleted file mode 100644 index 87e6063b..00000000 --- a/components/TabbedCommandBar/samples/TabbedCommandBarCustomSample.xaml +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/components/TabbedCommandBar/samples/TabbedCommandBarCustomSample.xaml.cs b/components/TabbedCommandBar/samples/TabbedCommandBarCustomSample.xaml.cs deleted file mode 100644 index 60cc4d62..00000000 --- a/components/TabbedCommandBar/samples/TabbedCommandBarCustomSample.xaml.cs +++ /dev/null @@ -1,30 +0,0 @@ -// 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; - -/// -/// An example sample page of a custom control inheriting from Panel. -/// -[ToolkitSampleTextOption("TitleText", "This is a title", Title = "Input the text")] -[ToolkitSampleMultiChoiceOption("LayoutOrientation", "Horizontal", "Vertical", Title = "Orientation")] - -[ToolkitSample(id: nameof(TabbedCommandBarCustomSample), "Custom control", description: $"A sample for showing how to create and use a {nameof(TabbedCommandBar)} custom control.")] -public sealed partial class TabbedCommandBarCustomSample : Page -{ - public TabbedCommandBarCustomSample() - { - this.InitializeComponent(); - } - - // TODO: See https://github.com/CommunityToolkit/Labs-Windows/issues/149 - public static Orientation ConvertStringToOrientation(string orientation) => orientation switch - { - "Vertical" => Orientation.Vertical, - "Horizontal" => Orientation.Horizontal, - _ => throw new System.NotImplementedException(), - }; -} diff --git a/components/TabbedCommandBar/samples/TabbedCommandBarSample.xaml b/components/TabbedCommandBar/samples/TabbedCommandBarSample.xaml new file mode 100644 index 00000000..825a1da2 --- /dev/null +++ b/components/TabbedCommandBar/samples/TabbedCommandBarSample.xaml @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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/TabbedCommandBar.xaml b/components/TabbedCommandBar/src/TabbedCommandBar.xaml index 8f6bbc65..467f517b 100644 --- a/components/TabbedCommandBar/src/TabbedCommandBar.xaml +++ b/components/TabbedCommandBar/src/TabbedCommandBar.xaml @@ -1,23 +1,33 @@ + - - - 0,4 - 4,0 - 8 - 1 + + - + + + + + + + + + + + + 0,4 + 4,0 + 8 + 1 + + + + + + + + + + + + + + + + - + - + - + - - - -