Sunny
Sunny

Reputation: 4809

How to set style property of an element in WPF

If IsEnabled property is true, I need to set the Style attribute otherwise it shouldn't be set. In the examples I've seen so far, style properties are set but not the style attribute itself. Below code is not working using Triggers.

<TabItem.Style>
                            <Style TargetType="TabItem">
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding IsEnabled}" Value="True">
                                        <Setter Property="Style" Value="DotcomTabItemStyle" />
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </TabItem.Style>

Upvotes: 3

Views: 5841

Answers (1)

almulo
almulo

Reputation: 4978

Since you're setting the Trigger through Style, changing the Style would also remove the Trigger... Not really sure if that'll work out :P

Anyway, you're making a mistake on your Setter (setting the resource name directly, not through a static or dynamic resource reference). And you don't need a DataTrigger. It should be:

<Trigger Property="IsEnabled" Value="True">
    <Setter Property="Style" Value="{StaticResource DotcomTabItemStyle}" />
</Trigger>

But as I said, this won't probably work as intended, since you're trying to modify the Style property from within the current Style...

One way or another, you'll end up adding different Setters for each property, probably either modifying the DotcomTabItemStyle Style you already have, or creating a new one (based on that one, maybe).

EDIT - Or you could use a Converter and bind the Style property to the IsEnabled property.

I've created a reusable Converter for all this kind of situations:

public class ConditionalSetterConverter : IValueConverter
{
    public bool Inverse { get; set; }

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        bool flag = (bool)value;

        if (flag ^ Inverse)
            return parameter;
        else
            return Binding.DoNothing;
    }

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

You use it like this:

<Window>
    <Window.Resources>
        <converters:ConditionalSetterConverter x:Key="InverseConditionalSetterConverter"
                                               Inverse="True" />
        <Style x:Key="DotcomTabItemStyle" TargetType="TabItem">...</Style>
    </Window.Resources>

    <TabControl>
        <TabItem Style="{Binding IsEnabled, 
                                 RelativeSource={RelativeSource Mode=Self},
                                 Converter={StaticResource InverseConditionalSetterConverter},
                                 ConverterParameter={StaticResource DotcomTabItemStyle}}" />
    </TabControl>
</Window>

EDIT 2 - OR... You could use a Style selector. ItemsControls like TabControl have a property called ItemContainerStyleSelector, of type StyleSelector.

You'd have to create your own class, inheriting StyleSelector, and override the SelectStyle function to include your custom logic there.

Something like this:

public class DotcomTabItemStyleEnabledSelector : StyleSelector
{
    private Style style = null;

    public override System.Windows.Style SelectStyle(object item, System.Windows.DependencyObject container)
    {
        var tabItem = container as TabItem;

        if (tabItem != null && tabItem.IsEnabled)
        {
            if (style == null)
                style = textBox.TryFindResource("DotcomTabItemStyle") as Style;

            return style;
        }

        return null;
    }
}

I've never used Style selectors, so I'm not really sure if this would work out of the box, but at least you get the idea.

Upvotes: 5

Related Questions