Search code examples
wpfstylesdatatemplate

WPF Style ListBox with ItemStyle and DataTemplate


I'm using WPF 4.5.2 and .Net 4.7.2

My base style looks like this

<Style x:Key="MyListBoxItem" TargetType="{x:Type ListBoxItem}" >

    <Setter Property="Template">

        <Setter.Value>

            <ControlTemplate TargetType="{x:Type ListBoxItem}">

                <Grid>

                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"  />
                        <ColumnDefinition Width="*"     />
                    </Grid.ColumnDefinitions>


                    <Border Grid.Column="0" BorderBrush="Black" BorderThickness="1,0,1,1">

                        <TextBox    Text="{Binding MyText}" />

                    </Border>


                    <Border Grid.Column="1" BorderBrush="Black" BorderThickness="0,0,1,1">

                        <ContentPresenter />

                    </Border>

                </Grid>


            </ControlTemplate>

        </Setter.Value>

    </Setter>

</Style>

furthermore, there are several DataTemplates looking something like this

<DataTemplate x:Key="SomeDataTemplate">

    <TextBox    Text="{Binding SomeString}" x:Name="txtContent"  Style="{DynamicResource MyStyle}" />

</DataTemplate>

I'm using a DataTemplateSelector class. Everything is recognized correctly, so there isn't any issue in terms of setting the ItemContainerStyle or the DataTemplateSelector.

But the style of the TextBox in the ControlTemplate of the ListBoxItem should be changed as well as the style the TextBox in the DataTemplate.

Is that possible or do I have move the ControlTemplate entirely to the DataTemplate?


Solution

  • I recommend to move all data related controls, i.e. controls that bind to the item's DataContext to the DataTemplate. Then use a DataTrigger to switch between different styles that targets the TextBox.

    <DataTemplate x:Key="SomeDataTemplate">
      <StackPanel>
        <TextBox x:Name="TxtContent" 
                 Style="{StaticResource DefaultStyle}" />
    
        <TextBox x:Name="OtherTxtContent"
                 Style="{StaticResource OtherDefaultStyle}" />
      </StackPanel>
    
    
      <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding SomeProperty}" Value="True" >
          <Setter TargetName="TxtContent" Property="Style" Value="{StaticResource AlternativeTextBoxStyle}" />
          <Setter TargetName="OtherTxtContent" Property="Style" Value="{StaticResource OtherAlternativeTextBoxStyle}" />
        </DataTrigger>
      </DataTemplate.Triggers>
    </DataTemplate>