views:

331

answers:

1

This question is very similar to Change WPF DataTemplate..., which I have read and implemented. It worked beautifully at first, but I ran into a problem with it.

That problem is that, when using themes in your application such as those in the WPF Futures project (e.g. Expression Dark), the ListBoxItems all revert back to the default WPF styling. This breaks the theme for those elements and, for example, produces black text on black background where the text would otherwise be white. This also affected my TreeView, and presumably would affect other similar controls.

I think this is because conflicting styles are being set for ListBox.ItemContainerStyle--one from the theme and one for switching data templates.

I've looked around for other solutions, but haven't found anything yet. Here are the leads or ideas I've had so far:

  1. Subclassing DataTemplateSelector and setting it to ListBox.ItemTemplateSelector. (The current best bet).
  2. Somehow, somewhere use a Trigger, DataTrigger, or EventTrigger.
  3. Give up on themes.
  4. Somehow hack the functionality I want into the theme.
  5. Somehow make my custom ItemContainerStyle somehow inherit it's colors and eye candy from the theme's style. (I tried it briefly, and it didn't work.)

Here is my ListBox and related pieces:

<Window.Resources>

  <DataTemplate x:Key="NormalTemplate">
      ...
  </DataTemplate>

  <DataTemplate x:Key="SelectedTemplate">
      ...
  </DataTemplate>

</Window.Resources>

<ListBox x:Name="RegisterListBox" Grid.Row="0"
         HorizontalContentAlignment="Stretch"
         ItemsSource="{Binding Adjustments}">

    <!-- this is from the post referenced above -->
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="ContentTemplate" Value="{StaticResource NormalTemplate}"/>
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="ContentTemplate" Value="{StaticResource SelectedTemplate}"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

The Listbox.DataContext is set in code to enable the ItemsSource binding.

Any ideas how I can achieve the kind of functionality described above while maintaining seamless support for themes?

+2  A: 

Have you tried doing something like this?

<ListBox.ItemContainerStyle>
    <Style 
        TargetType="{x:Type ListBoxItem}" 
        BasedOn="{StaticResource {x:Type ListBoxItem}}">    <=====
...

The idea is that the framework will first go look for a style with a key equal to typeof(ListBoxItem), it will find it in the themes, and then your style will just extend the themed one with your specific details.

arconaut
It worked. I had thought of using BasedOn, but I thought I couldn't do that because the theme's styles have no keys/names. I never thought about pointing it to to the type. Thanks a lot!
Benny Jobigan