Search code examples
wpflistboxlistboxitemtemplatebindingitemcontainerstyle

set value for listboxitem templated binding


I have this style:

<Style x:Key="SelectableListBoxItemStyle" TargetType="{x:Type ListBoxItem}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListBoxItem}">

                <Border Background="Transparent"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        CornerRadius="4"
                        BorderThickness="2"
                        x:Name="IconBorder"
                        Margin="4,2,4,2">
                    <ContentPresenter/>
                </Border>

                <ControlTemplate.Triggers>
                    <Trigger Property="IsSelected" Value="true">
                        <Setter TargetName="IconBorder" 
                                Property="BorderBrush" 
                                Value="Blue" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

My problem is that I don't know which property to set on the ListBox, when consuming my style so that the borders of it's ListBoxItems would end up having the desired border brush. I would also like to make this work for the other border brush in my style.

I would like to be able to have two list boxes with this same style but different border colors. I have this for a ListBox:

    <ListBox 
        ItemsSource="{Binding SelectedProduct.Pictures}"
        SelectedItem="{Binding SelectedSet, Mode=TwoWay}"
        ItemContainerStyle="{StaticResource ResourceKey= SelectableListBoxItemStyle}">
    </ListBox>

Update..I tried this:

    <ListBox 
        ItemsSource="{Binding SelectedProduct.Pictures}"
        SelectedItem="{Binding SelectedSet, Mode=TwoWay}">

            <ListBox.ItemContainerStyle>
                <Style TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource SelectableListBoxItemStyle}">
                    <Setter TargetName="IconBorder" Property="BorderBrush" Value="Green" />
                </Style>
            </ListBox.ItemContainerStyle>

        </ListBox>

But, I get: Error 8 TargetName property cannot be set on a Style Setter.


Solution

  • Instead of using a TemplateBinding you should try using a relative source binding.

    BorderBrush="{Binding RelativeSource={RelativeSource FindAncestor, 
                                          AncestorType={x:Type Listbox}}, 
                                          Path=BorderBrush}"
    

    If you want to have a different border than that defined for the ListBox then you will need to add a brush resource to your ResourceDictionary and apply that instead:

    <Listbox.Resources>
        <SolidColorBrush x:Key="MyListBoxItemBorderBrush" Color="Red"/>
    <Listbox.Resources>
    

    and then in your template:

    BorderBrush="{StaticResource MyListBoxItemBorderBrush}"
    

    If you need certain items to have different borders then you need to look at a StyleSelector.