Search code examples
wpfxamllistboxitemcontainerstyle

DataTrigger not changing template in ItemContainerStyle for Listbox


my idea is to change appearance of ListboxItem when MouseOver or Button is clicked etc.

<ListBox Name="listbox"
         Height="250"
         Grid.Row="4"
         Grid.ColumnSpan="5"
         HorizontalAlignment="Center">
  <ListBox.ItemContainerStyle>
    <Style TargetType="ListBoxItem">
      <Style.Triggers>
        <Trigger Property="IsMouseOver"
                 Value="True">
          <Setter Property="Template"
                  Value="{StaticResource control_mouseover}" />
        </Trigger>
        <Trigger Property="IsMouseOver"
                 Value="False">
          <Setter Property="Template"
                  Value="{StaticResource control_not_mouseover}" />
        </Trigger>
        <DataTrigger Binding="{Binding ElementName=grid.Artykuły, Path=IsPressed}"
                     Value="True">
          <Setter Property="Template"
                  Value="{StaticResource control_mouseover}" />
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </ListBox.ItemContainerStyle>
</ListBox>

Only for events IsMouseOver it works but DataTrigger does not seem to work Do you happen to know why?

<ControlTemplate x:Key="control_not_mouseover"
                 TargetType="ListBoxItem">
  <Border BorderBrush="Transparent">
    <ContentPresenter x:Name="contentPresenter"
                      Content="{TemplateBinding Content}"
                      ContentTemplate="{StaticResource not_mouseover}"
                      HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                      Margin="{TemplateBinding Padding}" />
  </Border>
</ControlTemplate>
<ControlTemplate x:Key="control_mouseover"
                 TargetType="ListBoxItem">
  <ContentPresenter x:Name="contentPresenter"
                    Content="{TemplateBinding Content}"
                    ContentTemplate="{StaticResource mouseover}"
                    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                    Margin="{TemplateBinding Padding}" />
</ControlTemplate>
<StackPanel>
  <Grid Name="grid"
        Height="240">
    <Button  Name="Artykuły"
             Grid.Column="0"
             Content="{Binding Path=liczba_wpisow, Converter={StaticResource wpisy_converter}}" /> [...]
  </Grid>
  <Listbox... />
</StackPanel>

Solution

  • I see a number of problems with your code. The first is that you don't need to add a Trigger for both true and false conditions. Instead, you should do this:

    <ListBox Name="listbox" Height="250" Grid.Row="4" Grid.ColumnSpan="5" HorizontalAlignment="Center">
        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Setter Property="Template" Value="{StaticResource control_not_mouseover}"/>
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Template" Value="{StaticResource control_mouseover}"/>
                    </Trigger>
                    <DataTrigger Binding="{Binding ElementName=grid.Artykuły, Path=IsPressed}" Value="True">
                        <Setter Property="Template" Value="{StaticResource control_mouseover}"/>
                    </DataTrigger>                  
                </Style.Triggers>
            </Style>
        </ListBox.ItemContainerStyle>
    </ListBox>
    

    However, this should not cause an actual error.

    The second problem is that the ElementName property show be set to the actual name of the relevant control and not to the type and name:

    <DataTrigger Binding="{Binding ElementName=Artykuły, Path=IsPressed}" Value="True">
        <Setter Property="Template" Value="{StaticResource control_mouseover}"/>
    </DataTrigger>
    

    UPDATE >>>

    To permanently apply your Template rather than just having it when the Button is pressed, just remove the DataTrigger and move the Setter out of the Triggers collection:

    <ListBox Name="listbox" Height="250" Grid.Row="4" Grid.ColumnSpan="5" HorizontalAlignment="Center">
        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Setter Property="Template" Value="{StaticResource control_not_mouseover}"/>
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Template" Value="{StaticResource control_mouseover}"/>
                    </Trigger>            
                </Style.Triggers>
            </Style>
        </ListBox.ItemContainerStyle>
    </ListBox>
    

    Unfortunately, your Setter values clashed, so I had to swap them over to make it work this way, but I believe that you can re-arrange it as you see fit.