Choose control style in XAML through converter.

Frequently we need to change control style (or template) dynamic. Of course it can be done on different ways:

  • Put two controls and “play” with Visibility property and binding – I suppose it’s the less smart case;
  • You can choose DataTemplate/ControlTemplate in code behind file;
  • And use converter.

I’ll show the last one.

The task is: we have a control (in my case it’s just an expand/collapse button) and we need to choose appropriate style for this control which depends on a model.

I created two styles:

  1. True style for expanded state
     <Style TargetType="Button">
                    <Setter Property="Width" Value="13" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate>
                                <Grid Width="13" Height="13" VerticalAlignment="Center" HorizontalAlignment="Center" Background="Transparent" Cursor="Hand">
                                    <Rectangle StrokeThickness="1" Stroke="{Binding ForegroundColor}" RadiusX="2" RadiusY="2" />
                                    <Rectangle Fill="{Binding ForegroundColor}" Height="1" VerticalAlignment="Center" Margin="3" />
                                </Grid>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
  1. False style for collapsed state
    <Style TargetType="Button">
                    <Setter Property="Width" Value="13" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate>
                                <Grid Width="13" Height="13" VerticalAlignment="Center" HorizontalAlignment="Center" Background="Transparent" Cursor="Hand">
                                    <Rectangle StrokeThickness="1" Stroke="{Binding ForegroundColor}" RadiusX="2" RadiusY="2" />
                                    <Rectangle Fill="{Binding ForegroundColor}" Height="1" VerticalAlignment="Center" Margin="3" />
                                    <Rectangle Fill="{Binding ForegroundColor}" Width="1" HorizontalAlignment="Center" Margin="3"  />
                                </Grid>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>

Next step, I create a BoolToStyleConverter:

    public class BoolToStyleConverter : IValueConverter
    {
        public Style TrueStyle { get; set; }

        public Style FalseStyle { get; set; }

        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return ((bool)value) ? TrueStyle : FalseStyle;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }

Also I create model with following properties:

    public class TaskModel
    {
        public bool IsExpanded { get; set; }

        public Brush ForegroundColor { get; set; }
    }

As a result, I’ve got following behavior only in a XAML. Additionally, I can use a bind (in my case it’s just a foreground color of the model to my style).

Expanded state

Collapsed state

Enjoy!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s