Reputation: 141
In frameworks like Bootstrap, there is an attribute (e.g. variant="primary"
) that can be set on buttons to give them a style/color that matches a specific user scenario:
I'm trying to figure out how to create a custom Button in WinUI that mimics this behavior. It would be styled using a dependency property like this:
<local:VariantButton Variant="Primary" />
I've created a custom Button that has the necessary dependency property, but now I'm trying to figure out how to change the button's color whenever the property changes. This is where I'm a little stuck on how to change the color.
I know that the button's colors comes from pre-defined theme dictionary brushes that can be overridden like this:
<Button.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Dark">
<!--Normal-->
<SolidColorBrush x:Key="ButtonBackground" Color="Black" />
<SolidColorBrush x:Key="ButtonBorderBrush" Color="DarkGray" />
<SolidColorBrush x:Key="ButtonForeground" Color="White" />
</ResourceDictionary>
<ResourceDictionary x:Key="Light">
<!--...-->
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Button.Resources>
And then I can switch between themes/dictionaries at runtime like this:
if (...) {this.RequestedTheme = ElementTheme.Dark;}
else {this.RequestedTheme = ElementTheme.Light;}
But when doing this, the RequestedTheme
property is of type ElementTheme
, which only has values for the built in Light and Dark themes:
So if the brushes that control the button's color live in themes that need to be overridden, and I can only switch between two pre-defined themes (Light and Dark), how do I create additional custom themes to implement my desired behavior (Primary/Secondary/Success/Warning/Danger/etc.). I know I can create a copy of the built-in Button control's XAML markup and then have full control over it, but there has to be a better way?
Upvotes: 1
Views: 701
Reputation: 13666
Since you want to switch colors depending on a parameter, Variant in this case, you might need to apply the changes inside your custom button. Besides the Background
and the Foreground
, you can also set the brushes used in the VisualStates
.
For example, let's say you have the Variant as a DependencyProperty
.
if (Variant is "Primary")
{
Background = Colors.AliceBlue;
this.Resources["ButtonBackgroundPointerOver"] = Colors.Blue;
this.Resources["ButtonBorderBrushPointerOver"] = Colors.SkyBlue;
this.Resources["ButtonForegroundPointerOver"] = Colors.LightBlue;
}
Upvotes: 1
Reputation: 2130
A code explanation for Classes derived from Control can override OnApplyTemplate callback to adjust the property values that were set by templates before the style is in use.
1.
public sealed class CustomControl1 : Button
{
public CustomControl1()
{
this.DefaultStyleKey = typeof(CustomControl1);
}
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
var ContentPresenter = this.GetTemplateChild("ContentPresenter") as ContentPresenter;
//add your code. if else
ContentPresenter.Background = new SolidColorBrush(Colors.Green);
}
}
<Style TargetType="local:CustomControl1" BasedOn="{StaticResource DefaultButtonStyle}">
</Style>
Here is Button's DefaultButtonStyle.
<local:CustomControl1>Success</local:CustomControl1>
Upvotes: 0