diff --git a/samples/ControlCatalog/Pages/CommandBar/CommandBarCustomizationPage.xaml b/samples/ControlCatalog/Pages/CommandBar/CommandBarCustomizationPage.xaml index 3ce911d9f8..16765b4921 100644 --- a/samples/ControlCatalog/Pages/CommandBar/CommandBarCustomizationPage.xaml +++ b/samples/ControlCatalog/Pages/CommandBar/CommandBarCustomizationPage.xaml @@ -29,10 +29,19 @@ HorizontalAlignment="Stretch" SelectionChanged="OnBgPresetChanged"> - - - - + + + + + + + + + + + + + @@ -41,8 +50,15 @@ HorizontalAlignment="Stretch" SelectionChanged="OnFgChanged"> - - + + + + + + + + + diff --git a/samples/ControlCatalog/Pages/CommandBar/CommandBarCustomizationPage.xaml.cs b/samples/ControlCatalog/Pages/CommandBar/CommandBarCustomizationPage.xaml.cs index 52c98757f0..2445bde045 100644 --- a/samples/ControlCatalog/Pages/CommandBar/CommandBarCustomizationPage.xaml.cs +++ b/samples/ControlCatalog/Pages/CommandBar/CommandBarCustomizationPage.xaml.cs @@ -14,16 +14,16 @@ namespace ControlCatalog.Pages { if (LiveBar == null) return; - - switch (BgPresetCombo.SelectedIndex) + + if (BgPresetCombo.SelectedItem is not ComboBoxItem { Tag: string preset }) { - case 1: - LiveBar.Background = new SolidColorBrush(Color.Parse("#0078D4")); - break; - case 2: - LiveBar.Background = new SolidColorBrush(Color.Parse("#1C1C1E")); - break; - case 3: + LiveBar.ClearValue(BackgroundProperty); + return; + } + + switch (preset) + { + case "Gradient": LiveBar.Background = new LinearGradientBrush { StartPoint = new Avalonia.RelativePoint(0, 0, Avalonia.RelativeUnit.Relative), @@ -35,11 +35,11 @@ namespace ControlCatalog.Pages } }; break; - case 4: + case "Transparent": LiveBar.Background = Brushes.Transparent; break; default: - LiveBar.ClearValue(BackgroundProperty); + LiveBar.Background = new SolidColorBrush(Color.Parse(preset)); break; } } @@ -48,19 +48,14 @@ namespace ControlCatalog.Pages { if (LiveBar == null) return; - - switch (FgCombo.SelectedIndex) + + if (FgCombo.SelectedItem is ComboBoxItem { Tag: string color }) { - case 1: - LiveBar.Foreground = Brushes.White; - break; - case 2: - LiveBar.Foreground = Brushes.Black; - break; - default: - LiveBar.ClearValue(ForegroundProperty); - break; + LiveBar.Foreground = new SolidColorBrush(Color.Parse(color)); + return; } + + LiveBar.ClearValue(ForegroundProperty); } private void OnRadiusChanged(object? sender, Avalonia.Controls.Primitives.RangeBaseValueChangedEventArgs e) diff --git a/src/Avalonia.Controls/CommandBar/CommandBarButton.cs b/src/Avalonia.Controls/CommandBar/CommandBarButton.cs index 776f4edc47..1eb7317cce 100644 --- a/src/Avalonia.Controls/CommandBar/CommandBarButton.cs +++ b/src/Avalonia.Controls/CommandBar/CommandBarButton.cs @@ -5,12 +5,6 @@ namespace Avalonia.Controls /// public class CommandBarButton : Button, ICommandBarElement { - static CommandBarButton() - { - ForegroundProperty.Changed.AddClassHandler((x, _) => x.UpdateIconForeground()); - IconProperty.Changed.AddClassHandler((x, _) => x.UpdateIconForeground()); - } - /// /// Defines the property. /// @@ -102,18 +96,5 @@ namespace Avalonia.Controls get => GetValue(IsInOverflowProperty); set => SetValue(IsInOverflowProperty, value); } - - private void UpdateIconForeground() - { - if (Icon is IconElement icon) - { - var fg = Foreground; - - if (fg != null) - icon.SetValue(ForegroundProperty, fg); - else - icon.ClearValue(ForegroundProperty); - } - } } } diff --git a/src/Avalonia.Controls/CommandBar/CommandBarToggleButton.cs b/src/Avalonia.Controls/CommandBar/CommandBarToggleButton.cs index 6d7ce4b61e..e1508feac4 100644 --- a/src/Avalonia.Controls/CommandBar/CommandBarToggleButton.cs +++ b/src/Avalonia.Controls/CommandBar/CommandBarToggleButton.cs @@ -7,12 +7,6 @@ namespace Avalonia.Controls /// public class CommandBarToggleButton : ToggleButton, ICommandBarElement { - static CommandBarToggleButton() - { - ForegroundProperty.Changed.AddClassHandler((x, _) => x.UpdateIconForeground()); - IconProperty.Changed.AddClassHandler((x, _) => x.UpdateIconForeground()); - } - /// /// Defines the property. /// @@ -104,18 +98,5 @@ namespace Avalonia.Controls get => GetValue(IsInOverflowProperty); set => SetValue(IsInOverflowProperty, value); } - - private void UpdateIconForeground() - { - if (Icon is IconElement icon) - { - var fg = Foreground; - - if (fg != null) - icon.SetValue(ForegroundProperty, fg); - else - icon.ClearValue(ForegroundProperty); - } - } } } diff --git a/src/Avalonia.Themes.Fluent/Controls/CarouselPage.xaml b/src/Avalonia.Themes.Fluent/Controls/CarouselPage.xaml index 25b5d67cb3..6415084dc9 100644 --- a/src/Avalonia.Themes.Fluent/Controls/CarouselPage.xaml +++ b/src/Avalonia.Themes.Fluent/Controls/CarouselPage.xaml @@ -14,7 +14,7 @@ - + diff --git a/src/Avalonia.Themes.Fluent/Controls/PathIcon.xaml b/src/Avalonia.Themes.Fluent/Controls/PathIcon.xaml index a3395ad99f..2a817ccfcb 100644 --- a/src/Avalonia.Themes.Fluent/Controls/PathIcon.xaml +++ b/src/Avalonia.Themes.Fluent/Controls/PathIcon.xaml @@ -10,7 +10,6 @@ - diff --git a/src/Avalonia.Themes.Simple/Controls/PathIcon.xaml b/src/Avalonia.Themes.Simple/Controls/PathIcon.xaml index 9e39ba4645..9e451cf966 100644 --- a/src/Avalonia.Themes.Simple/Controls/PathIcon.xaml +++ b/src/Avalonia.Themes.Simple/Controls/PathIcon.xaml @@ -3,7 +3,6 @@ x:ClassModifier="internal"> - diff --git a/tests/Avalonia.Controls.UnitTests/CommandBarTests.cs b/tests/Avalonia.Controls.UnitTests/CommandBarTests.cs index 371cbe4d6d..e368d93892 100644 --- a/tests/Avalonia.Controls.UnitTests/CommandBarTests.cs +++ b/tests/Avalonia.Controls.UnitTests/CommandBarTests.cs @@ -3,9 +3,14 @@ using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; using Avalonia.Controls; +using Avalonia.Controls.Presenters; using Avalonia.Controls.Primitives; +using Avalonia.Controls.Templates; using Avalonia.Input; using Avalonia.LogicalTree; +using Avalonia.Media; +using Avalonia.Styling; +using Avalonia.Themes.Simple; using Avalonia.Threading; using Avalonia.UnitTests; using Avalonia.VisualTree; @@ -118,6 +123,28 @@ public class CommandBarButtonTests : ScopedTestBase var btn = new CommandBarButton { CommandParameter = "param" }; Assert.Equal("param", btn.CommandParameter); } + + [Fact] + public void Foreground_DoesNotSetOrOverwriteIconElementForeground() + { + var icon = new PathIcon(); + var btn = new CommandBarButton + { + Icon = icon, + Foreground = Brushes.Red + }; + + Assert.False(icon.IsSet(TemplatedControl.ForegroundProperty)); + + btn.Foreground = Brushes.Blue; + + Assert.False(icon.IsSet(TemplatedControl.ForegroundProperty)); + + icon.Foreground = Brushes.Green; + btn.Foreground = Brushes.Red; + + Assert.Same(Brushes.Green, icon.Foreground); + } } public class CommandBarToggleButtonTests : ScopedTestBase @@ -205,6 +232,28 @@ public class CommandBarToggleButtonTests : ScopedTestBase var btn = new CommandBarToggleButton { CommandParameter = 42 }; Assert.Equal(42, btn.CommandParameter); } + + [Fact] + public void Foreground_DoesNotSetOrOverwriteIconElementForeground() + { + var icon = new PathIcon(); + var btn = new CommandBarToggleButton + { + Icon = icon, + Foreground = Brushes.Red + }; + + Assert.False(icon.IsSet(TemplatedControl.ForegroundProperty)); + + btn.Foreground = Brushes.Blue; + + Assert.False(icon.IsSet(TemplatedControl.ForegroundProperty)); + + icon.Foreground = Brushes.Green; + btn.Foreground = Brushes.Red; + + Assert.Same(Brushes.Green, icon.Foreground); + } } public class CommandBarSeparatorTests : ScopedTestBase @@ -309,6 +358,54 @@ public class CommandBarDefaultsTests : ScopedTestBase public void Content_DefaultIsNull() => Assert.Null(new CommandBar().Content); + [Fact] + public void Foreground_IsInheritedByCommandBarButtonPathIconThroughThemeTemplate() + { + using var app = UnitTestApplication.Start(TestServices.StyledWindow); + + var icon = new PathIcon(); + var btn = new CommandBarButton + { + Icon = icon + }; + var commandBar = new CommandBar + { + Foreground = Brushes.Red + }; + commandBar.PrimaryCommands.Add(btn); + + Assert.Same(icon, ApplySimpleThemeAndGetPresentedPathIcon(commandBar, btn)); + Assert.Same(Brushes.Red, icon.Foreground); + + commandBar.Foreground = Brushes.Blue; + + Assert.Same(Brushes.Blue, icon.Foreground); + } + + [Fact] + public void Foreground_IsInheritedByCommandBarToggleButtonPathIconThroughThemeTemplate() + { + using var app = UnitTestApplication.Start(TestServices.StyledWindow); + + var icon = new PathIcon(); + var btn = new CommandBarToggleButton + { + Icon = icon + }; + var commandBar = new CommandBar + { + Foreground = Brushes.Red + }; + commandBar.PrimaryCommands.Add(btn); + + Assert.Same(icon, ApplySimpleThemeAndGetPresentedPathIcon(commandBar, btn)); + Assert.Same(Brushes.Red, icon.Foreground); + + commandBar.Foreground = Brushes.Blue; + + Assert.Same(Brushes.Blue, icon.Foreground); + } + [Fact] public void PrimaryCommands_NotNull() => Assert.NotNull(new CommandBar().PrimaryCommands); @@ -370,6 +467,46 @@ public class CommandBarDefaultsTests : ScopedTestBase [Fact] public void ItemWidthCollapsed_DefaultIs42() => Assert.Equal(42d, new CommandBar().ItemWidthCollapsed); + + private static PathIcon ApplySimpleThemeAndGetPresentedPathIcon(CommandBar commandBar, TemplatedControl command) + { + var simpleTheme = new SimpleTheme(); + Assert.True(simpleTheme.TryGetResource(typeof(CommandBar), ThemeVariant.Default, out var commandBarTheme)); + Assert.True(simpleTheme.TryGetResource(command.GetType(), ThemeVariant.Default, out var commandTheme)); + commandBar.Theme = Assert.IsType(commandBarTheme); + command.Theme = Assert.IsType(commandTheme); + + var root = new TestRoot + { + Width = 500, + Height = 200, + Child = commandBar, + Styles = + { + simpleTheme + } + }; + + root.ApplyStyling(); + commandBar.ApplyStyling(); + commandBar.ApplyTemplate(); + root.LayoutManager.ExecuteInitialLayoutPass(); + + command.ApplyStyling(); + command.ApplyTemplate(); + + var presenter = command.GetTemplateChildren() + .OfType() + .Single(x => x.Name == "PART_IconPresenter"); + + presenter.ApplyStyling(); + presenter.UpdateChild(); + + var pathIcon = Assert.IsType(presenter.Child); + pathIcon.ApplyStyling(); + + return pathIcon; + } } public class CommandBarPropertyRoundTripTests : ScopedTestBase