Search code examples
c#xamluwpwinui

Change ExpanderHeader background color while hovering mouse Winui 2.x UWP


How to change ExpanderHeader background color while hovering mouse in Winui 2.x?

One of the way changing background is override StaticResource

<StaticResource
    x:Key="ExpanderHeaderBackground"
    ResourceKey="CardBackgroundFillColorDefaultBrush" />

Changing from code while hovering does not give any results:

        private void Expander_PointerEntered(object sender, PointerRoutedEventArgs e)
        {
            var expander = sender as Expander;
            expander.Resources["ExpanderHeaderBackground"] = Application.Current.Resources["ApplicationPageBackgroundThemeBrush"];
        }

        private void Expander_PointerExited(object sender, PointerRoutedEventArgs e)
        {
            var expander = sender as Expander;
            expander.Resources["ExpanderHeaderBackground"] = Application.Current.Resources["CardBackgroundFillColorDefaultBrush"];
        }

I do not want to recreate the whole style for this control only for changing Header background.

Expander source here: https://github.com/microsoft/microsoft-ui-xaml/blob/release/2.8/dev/Expander/Expander.xaml


Solution

  • You could set the Background property of the ToggleButton element in the visual tree directly:

    private void Expander_PointerEntered(object sender, PointerRoutedEventArgs e)
    {
        var expander = sender as Expander;
        var toggleButton = GetChildOfType<ToggleButton>(expander);
        toggleButton.Background = Application.Current.Resources["ApplicationPageBackgroundThemeBrush"] as Brush;
    }
    
    private void Expander_PointerExited(object sender, PointerRoutedEventArgs e)
    {
        var expander = sender as Expander;
        var toggleButton = GetChildOfType<ToggleButton>(expander);
        toggleButton.Background = Application.Current.Resources["CardBackgroundFillColorDefaultBrush"] as Brush;
    }
    
    private static T GetChildOfType<T>(DependencyObject depObj) where T : DependencyObject
    {
        if (depObj == default)
            return default;
    
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
        {
            var child = VisualTreeHelper.GetChild(depObj, i);
    
            var result = (child as T) ?? GetChildOfType<T>(child);
            if (result != default)
                return result;
        }
        return default;
    }