Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use a StyleSelector for a button

Tags:

.net

wpf

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?

like image 510
dandax Avatar asked Feb 22 '11 18:02

dandax


2 Answers

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.

like image 69
Skrymsli Avatar answered Oct 07 '22 03:10

Skrymsli


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();
    }
}
like image 21
Fredrik Hedblad Avatar answered Oct 07 '22 04:10

Fredrik Hedblad