Search code examples
c#uwpwinui

ThemeResource color doesn't follow app's theme UWP


I have a flyout that I created programmatically for my UWP app and I applied the SystemFillColorCautionBackgroundBrush background color from the WinUI gallery to it:

//create a flyout
var flyout = new Flyout();

//create a textblock
var textBlock = new TextBlock();
textBlock.Text =
    "Prima di salvare l'allegato è necessario contrassegnare la comunicazione come letta sul server. Confermi?";
textBlock.TextWrapping = TextWrapping.WrapWholeWords;
textBlock.Margin = new Thickness(0, 0, 0, 12);

var flyoutPresenterStyle = new Style(typeof(FlyoutPresenter));

flyoutPresenterStyle.Setters.Add(
    new Setter(
        FlyoutPresenter.BackgroundProperty,
        (Windows.UI.Xaml.Media.Brush)
            Application.Current.Resources["SystemFillColorCautionBackgroundBrush"]
    )
);

//make the flyout wrap the text vertically
flyoutPresenterStyle.Setters.Add(
    new Setter(ScrollViewer.HorizontalScrollModeProperty, ScrollMode.Disabled)
);
flyoutPresenterStyle.Setters.Add(
    new Setter(ScrollViewer.HorizontalScrollBarVisibilityProperty, ScrollBarVisibility.Disabled)
);

//make the flyoutPresenterStyle based on the default one
flyoutPresenterStyle.BasedOn = (Style)Application.Current.Resources["DefaultFlyoutPresenterStyle"];

flyout.FlyoutPresenterStyle = flyoutPresenterStyle;

//create a button
var button = new Button();
button.Content = "Leggi e apri";

The problem is that the theme of the background color I chose doesn't change based on my App's requested theme: enter image description here

How can I set the theme of that flyout background color?

Update 1: Also, I observed that on Windows 11 Version 22H2 this issue isn't present. This only happens on Windows 10.


Solution

  • It is recommended to use ThemeResource in xaml, it can re-evaluate when the theme changes, the code is as follows.

    <Button Content="Empty cart">
        <Button.Flyout>
            <Flyout>
                <Flyout.FlyoutPresenterStyle>
                    <Style TargetType="FlyoutPresenter">
                        <Setter Property="Background" Value="{ThemeResource SystemFillColorCautionBackgroundBrush}"/>
                    </Style>
                </Flyout.FlyoutPresenterStyle>
                <TextBlock TextWrapping="Wrap" Text="This is some text in a flyout."/>
            </Flyout>
        </Button.Flyout>
    </Button>
    

    Edit 2023/5/3

    If you want to access it from the code, you can create a new custom Flyout style, and use it from the code. For test, I define the style in App.xaml.cs. You can refer to the following code.

    App.xaml.cs

    <Application.Resources>
        <controls:XamlControlsResources>
            <controls:XamlControlsResources.MergedDictionaries>
                <!-- Other app resources here -->
                <ResourceDictionary>
                    <Style x:Name="NewflyoutStyle" TargetType="FlyoutPresenter" BasedOn="{StaticResource DefaultFlyoutPresenterStyle}">
                        <Setter Property="Background" Value="{ThemeResource SystemFillColorCautionBackgroundBrush}" />
                    </Style>
                </ResourceDictionary>
            </controls:XamlControlsResources.MergedDictionaries>
        </controls:XamlControlsResources>
    </Application.Resources>
    

    Page.xaml.cs

    var flyoutPresenterStyle = new Style(typeof(FlyoutPresenter));
    
    //flyoutPresenterStyle.Setters.Add(
    //    new Setter(
    //        FlyoutPresenter.BackgroundProperty,
    //        (Windows.UI.Xaml.Media.Brush)
    //            Application.Current.Resources["SystemFillColorCautionBackgroundBrush"]
    //    )
    //);
    
    //make the flyout wrap the text vertically
    flyoutPresenterStyle.Setters.Add(
        new Setter(ScrollViewer.HorizontalScrollModeProperty, ScrollMode.Disabled)
    );
    flyoutPresenterStyle.Setters.Add(
        new Setter(ScrollViewer.HorizontalScrollBarVisibilityProperty, ScrollBarVisibility.Disabled)
    );
    
    //make the flyoutPresenterStyle based on the custom one
    flyoutPresenterStyle.BasedOn = (Style)Application.Current.Resources["NewflyoutStyle"];
    
    flyout.FlyoutPresenterStyle = flyoutPresenterStyle;