Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I overwrite my ListBox's ItemTemplate and still keep the DisplayMemberPath?

I have a generic style for a ListBox that overwrites the ItemTemplate to use RadioButtons. It works great, EXCEPT when I set a DisplayMemberPath. Then I just get the .ToString() of the item in the ListBox.

I feel like I'm missing something simple here... can someone help me spot it?

<Style x:Key="RadioButtonListBoxStyle" TargetType="{x:Type ListBox}">
    <Setter Property="BorderBrush" Value="Transparent"/>
    <Setter Property="KeyboardNavigation.DirectionalNavigation" Value="Cycle" />
    <Setter Property="ItemContainerStyle">
        <Setter.Value>
            <Style TargetType="{x:Type ListBoxItem}" >
                <Setter Property="Margin" Value="2, 2, 2, 0" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <Border Background="Transparent">
                                <RadioButton
                                    Content="{TemplateBinding ContentPresenter.Content}" VerticalAlignment="Center"
                                    IsChecked="{Binding Path=IsSelected,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}"/>

                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Setter.Value>
    </Setter>
</Style>

My ListBox is bound to a List<T> of KeyValuePairs. If I remove the Style, the DisplayMemberPath shows up correctly so it must be something with the style.

<ListBox Style="{StaticResource RadioButtonListBoxStyle}"
         ItemsSource="{Binding MyCollection}"
         DisplayMemberPath="Value" SelectedValuePath="Key" />
like image 932
Rachel Avatar asked Sep 20 '11 14:09

Rachel


2 Answers

Why exactly do you want to keep DisplayMemberPath? Its just a shortcut for an ItemTemplate containing a TextBlock showing the value in DisplayMemberPath. With your own ItemTemplate you have much more flexibility what and how you want to display.

Just add a TextBlock into your ItemTemplate and set Text="{Binding Value}" and you have what you want.

As described here:

This property is a simple way to define a default template that describes how to display the data objects.

DisplayMemberPath provides a simple way to a template, but you want a different one. You can't and you don't need both.

like image 117
dowhilefor Avatar answered Oct 20 '22 00:10

dowhilefor


I still can't figure out how to get it to draw using the DisplayMemberPath, however I did find the piece I was missing to get it drawing using the ItemTemplate - I needed the ContentTemplate binding

<RadioButton 
    Content="{TemplateBinding ContentPresenter.Content}" 
    ContentTemplate="{TemplateBinding ContentPresenter.ContentTemplate}"
    IsChecked="{Binding Path=IsSelected,RelativeSource={
                        RelativeSource TemplatedParent},Mode=TwoWay}" />

Then in my XAML I can write:

<ListBox Style="{StaticResource RadioButtonListBoxStyle}"
         ItemsSource="{Binding MyCollection}"
         SelectedValuePath="Key">

    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Value}" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Thanks to dowhilefor for pointing out that DisplayMemberPath is simply a shortcut way of writing the ItemTemplate, and that both cannot be set at once.

like image 27
Rachel Avatar answered Oct 20 '22 00:10

Rachel