Search code examples
c#xamlwinui-3

How to swich the color theme in WinUI3 manually?


I want to build a combobox to let user choose which theme they want the app to display.

I added a combobox on my WinUI projects's settings page
The code go like this:

<!--XAML CODE-->

<ComboBox x:Name="themeMode" SelectionChanged="Themes_SelectionChanged">
    <ComboBoxItem>Light</ComboBoxItem>
    <ComboBoxItem>Dark</ComboBoxItem>
    <ComboBoxItem>Defaut</ComboBoxItem>                    
</ComboBox>

But I don't know how to defined "Themes_SelectionChanged"
(I have found some ways, but I think they're too complex to implement just this simple functionality, aren't there any simple way to acieve this?)


Solution

  • Let's say this ComboBox is in MainPage.xaml.

    <ComboBox x:Name="themeMode" SelectionChanged="Themes_SelectionChanged">
        <ComboBoxItem>Light</ComboBoxItem>
        <ComboBoxItem>Dark</ComboBoxItem>
        <ComboBoxItem>Defaut</ComboBoxItem>                    
    </ComboBox>
    

    then in MainPage.xaml.cs

    private void Themes_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (sender is ComboBox comboBox &&
            comboBox.SelectedItem is ComboBoxItem comboBoxItem &&
            comboBoxItem.Content is string themeString &&
            Enum.TryParse(themeString, out ElementTheme theme) is true)
        {
            this.RequestedTheme = theme;
        }
    }
    

    Also, instead of manually adding items in XAML, you can do it this way.

    In MainPage.xaml:

    public ImmutableArray<string> ElementThemeOptions { get; } = ImmutableArray.Create(Enum.GetNames<ElementTheme>());
    
    private void Themes_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (sender is ComboBox comboBox &&
            comboBox.SelectedValue is string themeString &&
            Enum.TryParse(themeString, out ElementTheme theme) is true)
        {
            this.RequestedTheme = theme;
        }
    }
    

    And in MainPage.xaml:

    <ComboBox
        ItemsSource="{x:Bind ElementThemeOptions}"
        SelectionChanged="Themes_SelectionChanged" />
    

    UPDATE

    Don't forget to do this in the root page, MainPage in this case.

    <Window
        ...
        ...>
        <local:MainPage />
    </Window>