wpfstylesskinningtheming

How do I Change colors of the native WPF control theme?


How can I change the foundation colours used by the native WPF control theming under Windows 10? I know there are libraries like MahApps.Metro, and MUI, but all I want to do is make the elements in my application drawn with consistent colours (MenuItem and Toolbar, I'm looking at you and your not-so-harmonious colors). I would also like to provide a variety of colour themes.

How do I do that?

I have to admit I just don't understand whether what I am asking is possible or not. Some investigation indicate that the default WPF theme uses static resources for things like the button background:

<Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>

If that resource is static, I guess I can't change it? Would it make sense to simply copy all the original WPF templates and replace static resources with dynamic resources somehow?


Solution

  • To do this "properly" for all controls and colours is rather more involved than you might imagine.

    Some of the brushes use windows theme colours, some use hard coded values.

    You can over-ride windows theme colours.

    For example, in a resource dictionary merged in app.xaml you could set your own preferences on all the colors and brushes.

    Here's one:

     <SolidColorBrush Color="LimeGreen" x:Key="{x:Static SystemColors.HighlightBrushKey}"/>
    

    https://learn.microsoft.com/en-us/dotnet/api/system.windows.systemcolors?view=netcore-3.1

    You will find this only changes some things though.

    You would have to re-template controls to replace the hard coded values.

    What do I mean by that?

    Take a look at the radiobutton template:

    https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/radiobutton-styles-and-templates?view=netframeworkdesktop-4.8

    In there you'll see stuff like:

              <Ellipse x:Name="Border"
                       StrokeThickness="1">
                <Ellipse.Stroke>
                  <LinearGradientBrush EndPoint="0.5,1"
                                       StartPoint="0.5,0">
                    <GradientStop Color="{DynamicResource BorderLightColor}"
                                  Offset="0" />
                    <GradientStop Color="{DynamicResource BorderDarkColor}"
                                  Offset="1" />
                  </LinearGradientBrush>
                </Ellipse.Stroke>
                <Ellipse.Fill>
                  <LinearGradientBrush StartPoint="0,0"
                                       EndPoint="0,1">
                    <LinearGradientBrush.GradientStops>
                      <GradientStopCollection>
                        <GradientStop Color="{DynamicResource ControlLightColor}" />
                        <GradientStop Color="{DynamicResource ControlMediumColor}"
                                      Offset="1.0" />
                      </GradientStopCollection>
                    </LinearGradientBrush.GradientStops>
                  </LinearGradientBrush>
                </Ellipse.Fill>
              </Ellipse>
    

    And those resources are defined in a big long list below the main template. You'd want to replace all these.

    Whether you want to make your controls all use windows theming or your own theme, you've got a lot of work to do if you start from scratch.

    You might want to take a look at the various pre-rolled themes which are available. Material design is quite popular seeing as a lot of people are familiar with android.

    http://materialdesigninxaml.net/