I have a requirement to change a button's style based on a value in the data. It looks like a StyleSelector would work perfectly but there doesn't seem to be a way to set one for a button.
Is there a way to set a button style dynamically from data? Maybe even a pure XAML approach?
A more general way to accomplish the same thing:
SomeView.xaml
<UserControl>
<UserControl.Resources>
<converters:BooleanToStyleConverter x:Key="MyButtonStyleConverter"
TrueStyle="{StaticResource AmazingButtonStyle}"
FalseStyle="{StaticResource BoringButtonStyle}"/>
</UserControl.Resources>
<Grid>
<Button Style={Binding IsAmazingButton, Converter={StaticResource MyButtonStyleConverter}}/>
</Grid>
</UserControl>
BooleanToStyleConverter.cs
public class BooleanToStyleConverter : IValueConverter
{
public Style TrueStyle { get; set; }
public Style FalseStyle { get; set; }
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is bool && (bool) value)
{
return TrueStyle;
}
return FalseStyle;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
This converter works in any view with any kind of control using whatever style you choose as long as you are binding to a Boolean property in your ViewModel to control the style switching. Easy to adapt it to other binding requirements though. This works in a DataTemplate as well.
You could place your Button
Styles in a Resource Dictionary and bind the Style for the Button
and use a Converter
ButtonStyles.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="ButtonStyle1" TargetType="Button">
<Setter Property="Background" Value="Green"/>
<Setter Property="FontSize" Value="12"/>
</Style>
<Style x:Key="ButtonStyle2" TargetType="Button">
<Setter Property="Background" Value="Red"/>
<Setter Property="FontSize" Value="14"/>
</Style>
</ResourceDictionary>
Then for the Button
that has this requirement you bind Style
to the property of interest
<Button ...
Style="{Binding Path=MyDataProperty,
Converter={StaticResource ButtonStyleConverter}}"/>
And in the Converter you load the ButtonStyles Resource Dictionary and return the desired Style based on the value
public class ButtonStyleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Uri resourceLocater = new Uri("/YourNameSpace;component/ButtonStyles.xaml", System.UriKind.Relative);
ResourceDictionary resourceDictionary = (ResourceDictionary)Application.LoadComponent(resourceLocater);
if (value.ToString() == "Some Value")
{
return resourceDictionary["ButtonStyle1"] as Style;
}
return resourceDictionary["ButtonStyle2"] as Style;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With