Override theme brush Windows 10 UWP - xaml

I'm trying to override some style-colors in Windows 10 but I cannot get it to work.
My app.xaml looks like this:
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources.xaml"/>
</ResourceDictionary.MergedDictionaries>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Default" Source="Theme.xaml"/>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Application.Resources>
And my Theme.xaml looks like this
<ResourceDictionary
x:Key="Default"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<SolidColorBrush x:Key="ListBoxBackgroundThemeBrush" Color="Transparent" />
<SolidColorBrush x:Key="ListBoxFocusBackgroundThemeBrush" Color="Transparent" />
<SolidColorBrush x:Key="ListBoxItemPressedBackgroundThemeBrush" Color="Transparent" />
<SolidColorBrush x:Key="ListBoxItemSelectedForegroundThemeBrush" Color="Transparent" />
<SolidColorBrush x:Key="ListBoxItemSelectedBackgroundThemeBrush" Color="Transparent" />
<SolidColorBrush x:Key="FocusVisualBlackStrokeThemeBrush" Color="Transparent" />
<SolidColorBrush x:Key="ScrollBarButtonForegroundThemeBrush" Color="Red" />
<SolidColorBrush x:Key="ScrollBarPanningBackgroundThemeBrush" Color="Red" />
<SolidColorBrush x:Key="ButtonPressedBackgroundThemeBrush" Color="White"/>
<SolidColorBrush x:Key="SearchBoxHitHighlightSelectedForegroundThemeBrush" Color="Red"/>
<SolidColorBrush x:Key="SearchBoxHitHighlightForegroundThemeBrush" Color="Pink"/>
However it doesn't work, it doesn't override the style anywhere.

The styles you are setting are for Windows 8 apps. The styles used by Universal Windows apps are greatly simplified.
The easiest way to find them is to add your ListBox to a page, right click on it in the designer, and select Edit Template... Create a copy of the template and look at the names used.
All of the controls now use the same brushes when possible rather than having control-specific ones.
For example, the ListBox uses the following brushes for its Foreground, Background, and BorderBrush:
SystemControlForegroundBaseHighBrush
SystemControlBackgroundChromeMediumLowBrush
SystemControlForegroundBaseHighBrush

To add to Rob's answer, for those looking for a broader app-wide response, it helped me to find the full default themes, which are available in
\(Program Files)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\<SDK version>\Generic folder of a Windows SDK installation, in themeresources.xaml.
In that is a ResourceDictionary for Default, HighContrast, and Light. The default key handles the Dark theme in UWP, since it is what will be defaulted to when no default "Dark" ResourceDictionary is found.
The Default and Light themes have nearly 1000 control-specific colors, or more generic "SystemControlForeground..." colors like Rob showed, but in UWP they are mostly based on the following 25 color categories:
24 system colors
SystemAccentColor, an OS-wide user-defined color which the UWP docs has a whole page about under Design & UI > Style > Color
There's 6 lighter and darker shades of the above (SystemAccentColorLight1, ...Dark1, etc) but they aren't used in the default resource dictionaries. However .6, .8 and .9 opacities of that color are used a handful of times, the only time opacities are used.
Then there are the 300+ color categories from Windows 8.1 that are left in, which manually pick a specific color, the extent of which you can see here
The only exception to the above is that the InkToolBar styling is almost exclusively derived from the High Contrast colors.
The High Contrast theme, pulls heavily from 8 additional System[blank]Colors that, similar to the SystemAccentColor, are OS-wide values. They're defined by templates and/or the user if they chose a High Contrast theme, which is an option Windows 10 has in its personalization settings. High Contrast is also an accessibility feature, so I think I'll be avoiding overriding that ResourceDictionary, no matter the app branding.
But effectively, by overriding the SystemAccentColor and the 24 System[blank]Colors in the XAML framework, you can effect the change of hundreds of specific color choices in a consistent way across an app.

Related

How to override user accent color in UWP app

I used Fluent XAML Theme Editor app to generate theme resources for my app.
My dark color scheme is black/grey with orange accent.
When I set accent color to green in Windows 10 Settings (see image below), this accent color comes through in some places.
As green and orange don't go well together, this looks really bad. How can I ensure that this does not happen?
Other similar questions on SO have answers that do NOT work for me (please do not mark as duplicate).
This is what I have done.
In Resource Dictionary I have defined orange accents for my "Dark" theme. This was generated by Fluent XAML Theme Editor (both accent and overrides are shades of orange):
<Windows10version1809:ColorPaletteResources Accent="#FFCC4D11"...
<!-- Override system generated accent colors -->
<Color x:Key="SystemAccentColorDark1">#FFD4632D</Color>
<Color x:Key="SystemAccentColorDark2">#FFDC7949</Color>
<Color x:Key="SystemAccentColorDark3">#FFE58E66</Color>
<Color x:Key="SystemAccentColorLight1">#FFB93E0E</Color>
<Color x:Key="SystemAccentColorLight2">#FFA62F0A</Color>
<Color x:Key="SystemAccentColorLight3">#FF932107</Color>
I have also added this as suggested elsewhere on SO:
<SolidColorBrush x:Key="SystemControlHighlightAccentBrush" Color="#FFCC4D11" />
However, none of this works and Windows Settings green comes through anyway. For example, an accent button appears green on mouse hover. Green also appears in combo boxes and radio buttons on mouse hover.
The button is defined like this:
<Button Style="{StaticResource AccentButtonStyle}" Content="Start"/>
This is what it looks like without and with hover. You don't need to be a graphic designer to know this is a bad look. I would like a different shade of orange to appear on hover. These shades are defined in the resource dictionary as SystemAccentColorDark1 - SystemAccentColorLight3, but they seem to be ignored for some reason.
How can I enforce my accent colors consistently? Obviously I do not want to have to re-style each control, I just want the colors from the resource dictionary to be used consistently.
UPDATE
System accent color is coming through even in Fluent XAML Theme Editor App itself, although not for the "Accent Button" but for "Check Box" and some other controls. See image where lime highlight is visible when mouse hovers over check box.
Found the problem.
In my app.xaml I had this for WinUI controls:
<Application>
<Application.Resources>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
</Application.Resources>
</Application>
In each page I had a color theme as a resource dictionary.
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ThemeDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Page.Resources>
For some reason that does not work correctly.
When I put both in the app.xaml and removed page resources, the weird problems with accent colors disappeared.
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
<ResourceDictionary Source="ThemeDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
I am now having problems with ContentDialog, but that's a different SO post. Something is not right with this resource merging it seems...
According to generic.xaml (in C:\Program Files (x86)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\10.0.19041.0\Generic), the AccentButtonStyle uses the following for hover background:
AccentButtonBackgroundPointerOver
Which is a resource using SystemControlForegroundAccentBrush, which is in turn using SystemAccentColor. This is the resource you need to override to avoid the system accent color coming through, for example:
<Color x:Key="SystemAccentColor">#FFFF00</Color>
If you put this resource in a global location (like in Application.xaml), it should override the accent colour everywhere.
I'm still not sure why the accent colour generated by Fluent Theme editor is not being applied though.
I have tested this on a simple blank app - MainPage.xaml:
<Grid>
<Button Style="{StaticResource AccentButtonStyle}" />
</Grid>
And App.xaml:
<Application
x:Class="App8.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App8">
<Application.Resources>
<Color x:Key="SystemAccentColor">#FF0000</Color>
</Application.Resources>
</Application>
One way to fix this, is to customize the control template.
I first copy the standard control template from:
C:\Program Files (x86)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\10.0.19041.0\Generic\themeresources.xaml
into my resource dictionary.
Then I painstakingly modify the template to eradicate the offending colors. Something like this:
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="RootGrid.(RevealBrush.State)" Value="PointerOver" />
<Setter Target="RootGrid.Background" Value="Transparent" />
<Setter Target="ContentPresenter.BorderBrush" Value="{ThemeResource SystemBaseLowColor}" />
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource SystemAccentColor}" />
</VisualState.Setters>
This is really tedious and unnecessary work, I am not sure why is no one from MS jumping on this. It is definitely not a problem just for me, this happens in the official Fluent XAML Editor app from MS.

Windows 10 Universal - proper way to manage font colors on different themes

I have a problem with themes on my Windows 10 Universal App. I'm testing it on phone. It works fine when I'm on light theme - Texts are black. But when I change theme to dark, the font stays dark and it cannot be seen.
I know I can manually programaticaly change font color to white when I'm on dark theme. But I doubt it is a proper way. How should I take care of white and black theme?
You can use the {StaticResource} markup extension
<RelativePanel x:Name="MymusicSubPanel" Background="{ThemeResource SystemControlTranslucentHighBrush}" ... >
...
</RelativePanel>
And you can use different color to your Theme.
<SolidColorBrush x:Key="SystemBackgroundAltHighBrush" Color="#FFF0F0F0"/>
How to use the Theme?You can use it in the Page resources.
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary Source="LightThemeDictionary.xaml" x:Key="Light"/>
<ResourceDictionary Source="DarkThemeDictionary.xaml" x:Key="Dark"/>
<ResourceDictionary Source="HighContrastBlackDictionary.xaml" x:Key="HighContrastBlack"/>
...
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Page.Resources>
You can use the Theme,you write the back is black and text foreground color is white.
https://embracez.xyz/xaml-uwp-themes/

How can I use a non-SolidColor brush for WinRT xaml TextBox foreground color?

I'm trying to style a TextBox such that the text is rendered with an Image brush, but I can't seem to get it to work.
Given, the following snippet, I am able to set the text to render with a solid color brush. However, if I instead try to use either of the commented out brushes (LinearGrad or ImageBrush), it just renders as solid black text.
<TextBox Text="test" Background="{x:Null}" FontSize="64">
<TextBox.Foreground>
<SolidColorBrush Color="Plum"/>
<!--<LinearGradientBrush StartPoint="0 0" EndPoint="1 0">
<GradientStop Color="White"/>
<GradientStop Color="Black" Offset="1"/>
</LinearGradientBrush>-->
<!--<ImageBrush ImageSource="ms-appx:/Assets/Texture.png"/>-->
</TextBox.Foreground>
</TextBox>
I can do the same thing to style a TextBlock, but it doesn't seem to work on a TextBox. Is there something I'm missing? The documentation makes no mention about any limitations or exceptions: MSDN Docs
To be clear, this is NOT a WPF question. I know this works in WPF, this is a Windows 8 App (WinRT).
Seems like it might be an undocumented unsupported scenario based on my testing. If you really need to do it though - you could create a custom template of the TextBox that displays a TextBlock when the control is not in use and template-bind the TextBlock.Foreground and other properties to the respective TextBox properties.

Change the default page color on a window 8 store application

When I create a new page on a windows 8 store application it has default color which I want to change. If I remove all elements on the page and change the background color it has no effect. I've set the back ground to pink in my example below. How can I make this color take effect? (I've also removed everything out of App.xaml)
<common:LayoutAwarePage
x:Name="pageRoot"
x:Class="DemoWindows8StoreApp.BasicPage3"
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:DemoWindows8StoreApp"
xmlns:common="using:DemoWindows8StoreApp.Common"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Background="Pink"
mc:Ignorable="d">
It's best to follow the default templates in that rather than setting the Background of the Page, but of the root element (usually a Grid), I'm not 100% sure why a Background on that page doesn't work (I suspect the control template).
UPDATE 1
According to Control.Background
Each control might apply this property differently based on its visual
template. This property only affects a control whose template uses the
Background property as a parameter. On other controls, this property
has no effect. For more info about visual templates, see the Template
property.
So there might be possible that Page's template doesn't use Background property as a parameter.
Remove nothing from the project to change the color. Go to Common\StandardStyles.xaml. Search for "LayoutRootStyle". You will find style for Panel. Change Background there. Please note this will be affected to all the pages in the project. If you want different color for different page then you can create separate style for each page.
<Style x:Key="LayoutRootStyle" TargetType="Panel">
<Setter Property="Background" Value="Pink"/>
<Setter Property="ChildrenTransitions">
<Setter.Value>
<TransitionCollection>
<EntranceThemeTransition/>
</TransitionCollection>
</Setter.Value>
</Setter>
</Style>

How to override TextBlock IsHitTestVisible across Silverlight app

I'll save my why did they do it this way rants for elsewhere, so...
I'm trying to prevent TextBlocks from getting focus across my Silverlight app. It seems like adding a setter for this property on any TextBlock within my application's base page class (Page-inheriting) makes some sense, but 1) I'm probably wrong and 2) I can't seem to quite get it right.
I've tried variations on adding code like this:
this.Style.Setters.Add(new Setter(TextBlock.IsHitTestVisibleProperty, false));
to the constructor of my app's base Page class (inherits directly from Page) or in a page Loaded event handler. But most variations on that theme don't seem to work (generally seeming as though all the right members don't yet exist or XamlParseExceptions.
It's probably absurdly simple, but so is my brain, apparently. Any ideas?
You could just use an implicit style
<Style TargetType="TextBlock">
<Setter Property="IsHitTestVisible" Value="False" />
</Style>
Generally, styles are merged at the top level of the App.xaml file if in separate resource dictionaries or you could simply add your style there. I'm pretty new to Silverlight myself, so I'm only reporting what I've seen.
Assuming you have an empty App.xaml starting out, it may look something like this:
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Class="YourApp.App"
mc:Ignorable="d">
<Application.Resources>
<ResourceDictionary>
<Style TargetType="TextBlock">
<Setter Property="IsHitTestVisible" Value="False" />
</Style>
</ResourceDictionary>
</Application.Resources>
</Application>
This is pretty simple to test, you could add a Foreground color setter and see if all of your TextBlocks pick up the style.