0

I want to set a DataTrigger for multiple DataTemplate but I am not sure if there is way to do that? I have view structured like below

<ItemsControl ItemsSource="{Binding Collection}"
              AlternationCount="2"
              ItemTemplateSelector="{StaticResource RowSelector}" >
<local:HeaderTemplateSelector x:Key="RowSelector"
            NormalTemplate="{StaticResource NormalTemplate}"
            ExpanderTemplate1="{StaticResource ExpanderTemplate1}"
            ExpanderTemplate2="{StaticResource ExpanderTemplate2}"
            ExpanderTemplate3="{StaticResource ExpanderTemplate3}"  />
<DataTemplate x:Key="NormalTemplate" ...>
    <stackpanel  x:Name="main"
<DataTemplate x:Key="ExpanderTemplate1" ...>
    <Grid  x:Name="main" ..>
<DataTemplate x:Key="ExpanderTemplate2" ...>
    <Expander  x:Name="main"
<DataTemplate x:Key="ExpanderTemplate3" ...>
    <Textblock  x:Name="main" ...>

I want this data trigger which provides alternative background for rows, the trigger defined below

<DataTemplate.Triggers>
    <Trigger Property="ItemsControl.AlternationIndex" Value="0">
        <Setter Property="Background" Value="Blue" TargetName="main"/>
    </Trigger>
    <Trigger Property="ItemsControl.AlternationIndex" Value="1">
        <Setter Property="Background" Value="black"  TargetName="main"/>
    </Trigger>
</DataTemplate.Triggers>

I can add this to the end of each DataTemplate and it works fine but it mean that I have to duplicate the some code 4 times, is there any way to avoid that? (I know I can use datagrid but it is overkill for this simple structure)

Fred Jand
  • 699
  • 7
  • 25
  • Maybe a dup of this: http://stackoverflow.com/questions/4443600/is-there-a-way-to-use-data-template-inheritance-in-wpf – Vlad Oct 16 '12 at 16:11
  • maybe you can add the triggers to a style, not to a template? you can reuse the style or base a new style off the base one. – Vlad Oct 16 '12 at 16:14
  • I don’t know any way to apply style here, because the trigger is based on “ItemsControl.AlternationIndex” which sets background so where can I apply Style in this case?! – Fred Jand Oct 16 '12 at 16:46
  • No room for the example in comments, added as answer. – Vlad Oct 16 '12 at 17:18

1 Answers1

3

You can try to set the trigger with the style:

<Style TargetType="Panel" x:Key="AlternatelyPainted">
    <Style.Triggers>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentPresenter}}, Path=(ItemsControl.AlternationIndex)}" Value="0">
            <Setter Property="Background" Value="Red"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentPresenter}}, Path=(ItemsControl.AlternationIndex)}" Value="1">
            <Setter Property="Background" Value="Blue"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

(code thankfully stolen from this answer) and use it in your templates:

<DataTemplate x:Key="NormalTemplate" ...>
    <StackPanel Style="{StaticResource AlternatelyPainted}">
        ...
    </StackPanel>
</DataTemplate>

etc.

Edit: if you want the style to be universal, not Panel-specific, you can try the following trick:

<Style x:Key="AlternatelyPainted">
    <Style.Triggers>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentPresenter}}, Path=(ItemsControl.AlternationIndex)}" Value="0">
            <Setter Property="Panel.Background" Value="Red"/>
            <Setter Property="Control.Background" Value="Red"/>
            <Setter Property="TextBlock.Background" Value="Red"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentPresenter}}, Path=(ItemsControl.AlternationIndex)}" Value="1">
            <Setter Property="Panel.Background" Value="Blue"/>
            <Setter Property="Control.Background" Value="Blue"/>
            <Setter Property="TextBlock.Background" Value="Blue"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

(removed the TargetType and added explicit types to the property names). Note that TextBlock doesn't inherit its Background, so we need an additional line for it.

Community
  • 1
  • 1
Vlad
  • 35,022
  • 6
  • 77
  • 199
  • It is ok for stackpanel and grid and other panel type elements. But this one has on problem, the type should be always Panel which is not true in my case, I have different types including controls like "Expander and "Textblock"! but I can wrap them in a panel at least as temporary a solution, it's better than duplication anyway, thanks. – Fred Jand Oct 16 '12 at 18:39
  • this helps my special case, but I wonder why it is not possible to set triggers properties like style? – Fred Jand Oct 21 '12 at 02:49