wingerse
wingerse

Reputation: 3796

Using StyleSelector with ItemContainerStyle

I have a ListBox whose ItemsSource is simply a list of strings. I have a style which changes the template of the ListBoxItems.
Here it is:

<Style x:Key="MyStyleBase" TargetType="{x:Type ListBoxItem}" >
    <Setter Property="Margin" Value="2" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                <StackPanel x:Name="stackPanel">
                    <CheckBox Focusable="False"
                    IsChecked="{Binding Path=IsSelected, Mode=TwoWay,
                    RelativeSource={RelativeSource TemplatedParent} }">
                        <ContentPresenter/>
                    </CheckBox>
                </StackPanel>
                <ControlTemplate.Triggers>
                    <Trigger Property="ItemsControl.AlternationIndex" Value="1">
                        <Setter TargetName="stackPanel" Property="Background" Value="LightBlue" />
                    </Trigger>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter TargetName="stackPanel" Property="Background" Value="Red"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

I apply this style to the ListBox using another style :

<Style x:Key="Style" TargetType="ListBox">
    <Setter Property="AlternationCount" Value="2"/>
    <Setter Property="ItemContainerStyle" Value="{StaticResource MyStyleBase}"/>
</Style>

Now this works great, until I want the foreground of the text of each ListBoxItem to be changed based on the string value of it. I am using a StyleSelector for this:

class MyStyleSelector : StyleSelector
{
    public override Style SelectStyle(object item, DependencyObject container)
    {
        if((string)item == "Avatar")
            return Application.Current.MainWindow.FindResource("MyStyleBlue") as Style;
        return Application.Current.MainWindow.FindResource("MyStyleBlack") as Style;
    }
}

Here are my MyStyleBlue and MyStyleBlack:

<Style x:Key="MyStyleBlack" BasedOn="{StaticResource MyStyleBase}" TargetType="{x:Type ListBoxItem}">
    <Setter Property="Foreground" Value="Black"></Setter>
</Style>

<Style x:Key="MyStyleBlue" BasedOn="{StaticResource MyStyleBase}" TargetType="{x:Type ListBoxItem}">
    <Setter Property="Foreground" Value="Blue"></Setter>
</Style>

It doesn't work when I have the string "Avatar" in the ListBoxItem. It just displays the usual MyStyleBase(With foreground unchanged). But The StyleSelector is supposed to change the style to MyStyleBlue if the ListBoxItem is "Avatar". MyStyleBlue is supposed to change the foreground to blue (But it doesn't). What am I doing wrong?

I saw this question which says StyleSelectors won't work if ItemContainerStyle is set. But then how do I use StyleSelector with ItemContainerStyle set? Is there any other way to do what I am wanting to do?

Upvotes: 2

Views: 1369

Answers (1)

Clemens
Clemens

Reputation: 128077

When you use an ItemStyleSelector the item styles are returned from that StyleSelector, so setting ItemContainerStyle at the same time has no effect.

However, that doesn't matter, because the styles that you return from MyStyleSelector are already based on MyStyleBase. There is no need at all to also set ItemContainerStyle to MyStyleBase.

Upvotes: 1

Related Questions