Closed geometrikal closed 2 years ago
Add a theme dictionary inside the <ui:ThemeResources>
element in App.xaml:
<ui:ThemeResources>
<ui:ThemeResources.ThemeDictionaries>
<ResourceDictionary x:Key="Dark">
</ResourceDictionary>
</ui:ThemeResources.ThemeDictionaries>
</ui:ThemeResources>
<ResourceDictionary x:Key="Dark">
<ResourceDictionary.MergedDictionaries>
<ui:DefaultThemeResources Key="Dark" />
</ResourceDictionary.MergedDictionaries>
3. Redefine the resource you want to override:
```xaml
<ResourceDictionary x:Key="Dark">
<ResourceDictionary.MergedDictionaries>
<ui:DefaultThemeResources Key="Dark" />
</ResourceDictionary.MergedDictionaries>
<ui:StaticResource x:Key="ButtonBorderBrush" ResourceKey="SystemControlBackgroundBaseMediumHighBrush" />
</ResourceDictionary>
Currently this doesn't seem to take effect at design time, but does work at run time. And usually you'll need to override the brushes used by other states (such as ButtonBorderBrushPointerOver
) as well.
Thank you.
On more question if I may. If I want to create a new colour that is derived from the accent colour, e.g. if none of the resource accent colours are exactly the right shade, is there an easy way to derive one?
BTW thanks for you work on this library. It is really really helpful, especially ContentDialog.
Glad to hear it's of help. Regarding the question, unfortunately there’s no built-in way to do this. For a starter something like this might work for simple scenarios:
public static class SolidColorBrushHelper
{
public static readonly DependencyProperty NegativeColorProperty =
DependencyProperty.RegisterAttached(
"NegativeColor",
typeof(Color),
typeof(SolidColorBrushHelper),
new PropertyMetadata(Colors.Transparent, OnNegativeColorChanged));
public static Color GetNegativeColor(SolidColorBrush brush)
{
return (Color)brush.GetValue(NegativeColorProperty);
}
public static void SetNegativeColor(SolidColorBrush brush, Color value)
{
brush.SetValue(NegativeColorProperty, value);
}
private static void OnNegativeColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var brush = (SolidColorBrush)d;
brush.Color = GetNegativeColor((Color)e.NewValue);
}
private static Color GetNegativeColor(Color color)
{
return Color.FromRgb((byte)(255 - color.R), (byte)(255 - color.G), (byte)(255 - color.B));
}
}
<SolidColorBrush x:Key="NegativeAccentColorBrush" local:SolidColorBrushHelper.NegativeColor="{DynamicResource SystemAccentColor}" />
Thanks, I did a variation on that with another dep prop to set the shading amount and it works.
I notice that some colours don't appear at all in the designer if the keys were overridden as <ui:StaticResource ..>
. Change it to <DynamicResource ..>
they appear in the designer but though an error when the app runs 😅 It will work if defined as a SolidColorBrush based off a DynamicResource, e.g.
<SolidColorBrush x:Key="ButtonBackground"
Color="{DynamicResource SystemBaseLowColor}"
Opacity="0.5" />
Also when creating an xaml with <ui:ContentDialog ..>
as a base, nothing appears at all in the designer.
Using StaticResource
this way is commonly seen in UWP and supported by the designer. Unfortunately in WPF I have to use a hack/workaround to get it working and the designer doesn't like it. To keep things in sync with UWP/WinUI I guess we'll have to live with it for now. Using a SolidColorBrush
should work too. One thing to note is that it's probably safer to use Color="{StaticResource SystemBaseLowColor}"
here. Using DynamicResource
might cause issues mentioned here in the "Troubleshooting theme resources" section.
I've committed a fix for the ContentDialog
issue and will push an update to NuGet soon. Thanks for reporting this.
Hello,
Is it still possible to override the default resources by taking into account the theme on v0.9.2?
As DefaultThemeResources
doesn't exist anymore, I don't know how to get it works.
In advance, thanks for your help and for this great library!
EDIT: It's okay, I just found
<ui:ThemeResources>
<ui:ThemeResources.ThemeDictionaries>
<ResourceDictionary x:Key="Light" ui:ThemeDictionary.Key="Light">
<StaticResource x:Key="TextControlBorderBrush" ResourceKey="SystemControlForegroundBaseMediumBrush" />
<StaticResource x:Key="TextControlBorderBrushPointerOver" ResourceKey="SystemControlHighlightBaseMediumHighBrush" />
</ResourceDictionary>
<ResourceDictionary x:Key="Dark" ui:ThemeDictionary.Key="Dark">
<StaticResource x:Key="TextControlBorderBrush" ResourceKey="SystemControlForegroundBaseMediumBrush" />
<StaticResource x:Key="TextControlBorderBrushPointerOver" ResourceKey="SystemControlHighlightBaseMediumHighBrush" />
</ResourceDictionary>
<ResourceDictionary x:Key="HighContrast" ui:ThemeDictionary.Key="HighContrast">
<StaticResource x:Key="TextControlBorderBrush" ResourceKey="SystemControlForegroundBaseMediumBrush" />
<StaticResource x:Key="TextControlBorderBrushPointerOver" ResourceKey="SystemControlHighlightBaseMediumHighBrush" />
</ResourceDictionary>
</ui:ThemeResources.ThemeDictionaries>
</ui:ThemeResources>
I want to give the buttons a border (in another project that uses the nuget package). How should I override the color key in my own resource dictionary?
For example, in Dark.xaml there is
<m:StaticResource x:Key="ButtonBorderBrush" ResourceKey="SystemControlForegroundTransparentBrush" />
If I want to set this to
SystemControlBackgroundBaseMediumHighBrush
what is the best way that will still respect the theme settings?