Search code examples
c#wpfxamldatatemplatecontroltemplate

How to design this ListViewItem


I want my ListViewItem to look like this. As you can see when the ListViewItem is selected/has focus the Border should change color.

The Main Problem is that I can't put a Border around the ContenPresenter in the ControlTemplate because than also the TextBox with the "Description"-Binding will be inside the Border. But I only want the TextBox and Icon to be inside the Border that changes Colors and not also the Description ("Nachname", "Vorname").

enter image description here

This is the XAML I have so far. I don't know how to change the border in the ControlTemplate:

<ListView x:Name="SearchFields" Grid.Row="0" Grid.Column="0" ItemsSource="{Binding CustomerSearchFields}" SelectedItem="{Binding selectedSearchField, UpdateSourceTrigger=LostFocus}" Style="{StaticResource MaterialDropShadowStyle}" 
              BorderThickness="0,0,2,0" Padding="24,24,24,0" HorizontalContentAlignment="Stretch" helper:EnterKeyTraversal.IsEnabled="True" KeyboardNavigation.TabNavigation="Cycle" FontFamily="{StaticResource DefaultFontFamily}"
              Background="{StaticResource ColorLightGray2}">
        <ListView.Resources>                
            <DataTemplate DataType="{x:Type model:CustomerSeachFieldViewModel}">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*" />
                        <RowDefinition Height="48" />
                    </Grid.RowDefinitions>

                    <TextBlock Grid.Row="0" Text="{Binding Description}" FontSize="{StaticResource FontSizeSmall}" FontWeight="SemiBold" Foreground="{StaticResource ColorDarkGray}" Margin="0,0,0,4" />
                    <Border x:Name="PART_Border" Grid.Row="1" BorderThickness="1" BorderBrush="{StaticResource ColorGray}">
                        <Grid Background="White">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="48" />
                            </Grid.ColumnDefinitions>

                            <TextBox Grid.Column="0" Text="{Binding SearchText}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" FontSize="{StaticResource FontSizeNormal}" Padding="12,15" BorderThickness="0" />
                            <Border Grid.Column="1" Background="{StaticResource ColorLightGray2}" Margin="8">
                                <ctrl:IconViewbox IconData="{StaticResource IconPathSearch}" IconSize="16" IsTabStop="False" />
                            </Border>                     
                        </Grid>
                    </Border>                        
                </Grid>                    
            </DataTemplate>
        </ListView.Resources>            
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">                    
                <Setter Property="IsTabStop" Value="False" />
                <Setter Property="Margin" Value="0,0,0,24" />                    
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate>                                
                            <ContentPresenter Content="{Binding}" />                                
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <Style.Triggers>
                    <Trigger Property="IsKeyboardFocusWithin" Value="True">
                        <Setter Property="IsSelected" Value="True" />
                    </Trigger>
                    <Trigger Property="IsSelected" Value="True">
                        <Trigger.Setters>                                
                            <Setter Property="BorderBrush" Value="Fuchsia" />
                        </Trigger.Setters>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </ListView.ItemContainerStyle>
    </ListView>

Solution

  • You can add a Trigger to your Border named PART_Border as follow:

    <Border x:Name="PART_Border" Grid.Row="1" BorderThickness="1" >
                        <Border.Style>
                            <Style TargetType="Border">
                                <Setter Property="BorderBrush" Value="DarkGray" />
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListViewItem}}}"
                                                 Value="True" >
                                        <Setter Property="BorderBrush" Value="Black"/>
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </Border.Style>
                        <Grid Background="White">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="48" />
                            </Grid.ColumnDefinitions>
    
                            <TextBox Grid.Column="0" 
                                     Text="{Binding SearchText}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" FontSize="15" Padding="12,15" BorderThickness="0" />
                            <Border Grid.Column="1" Background="Gray" Margin="8">
                                <Rectangle Width="20" Height="20" />
                            </Border>                     
                        </Grid>
                    </Border>
    

    Please note that I replaced some StaticResource mapped to some Colors from your code with standard color in order to test my code.

    I also replaced the icon with a Rectangle for the same reason.