Home > Software design >  Apply style to child content in WPF XAML with a template
Apply style to child content in WPF XAML with a template

Time:10-12

I'm using a ListViewto display a menu. I want to apply a style to all ListViewItem. So far I have succeeded in one part of the concern but I would like to improve to avoid code replication. Here where I am :

<Window.Resources>
    <Style x:Key="_listViewItemStyle" TargetType="ListViewItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListViewItem}">
                    <Border x:Name="Bd"
                       ...                  
                    </Border>
                    <ControlTemplate.Triggers>
                       ...
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

And then use the style like that :

 <ListView x:Name="_listViewMenu"
     Background="Transparent"
     BorderBrush="Transparent"
     ScrollViewer.HorizontalScrollBarVisibility="Disabled">
         <ListViewItem Style="{StaticResource _listViewItemStyle}">
             <StackPanel Orientation="Horizontal"
                       Width="230"
                       Margin="10,0,0,0">
                 <Image Width="30" 
                       Source="Images/Settings.png"
                       Stretch="Uniform"/>
                 <TextBlock Text="Paramètres"
                       Margin="25,0,0,0"
                       Style="{StaticResource _fontStyle}"/>
             </StackPanel>
         </ListViewItem>
 </ListView>

As you can see there are some stuff that I imagine I can avoid to duplicate if I have 50 ListViewItems, let's say :

<StackPanel Orientation="Horizontal"
                       Width="230"
                       Margin="10,0,0,0">

or

<Image Width="30"
     ...
Stretch="Uniform"/>

etc...

How to include in the style _listViewItemStyle all required properties to format StackPanel, Image, textbox, etc... of the ListViewItem?

Thanks.

CodePudding user response:

You can define a class which has necessary properties and use it as item type of collection for ItemsSource which may be in view (xaml or code behind). Such class would be as follows.

public class SourceItem
{
    public string? ImagePath { get; init; }
    public string? Text { get; init; }
}

Then, if you just want to show items, ItemsControl would be suffice. I don't know how you intend to use Triggers though.

<ItemsControl Background="Blue" HorizontalAlignment="Left">
    <local:SourceItem ImagePath="Images/Settings.png" Text="Paramètres"/>
    ...

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border x:Name="Bd">
                <StackPanel Orientation="Horizontal"
                            Width="230"
                            Margin="10,0,0,0">
                    <Image Width="30"
                           Source="{Binding ImagePath, Mode=OneTime}"
                           Stretch="Uniform"/>
                    <TextBlock Text="{Binding Text, Mode=OneTime}"
                               Margin="25,0,0,0"
                               Style="{StaticResource _fontStyle}"/>
                </StackPanel>
            </Border>

            <DataTemplate.Triggers>
                ...
            </DataTemplate.Triggers>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

CodePudding user response:

In addition to the answer from @emoacht, you will need the following InputBindings:

<Border.InputBindings>
    <MouseBinding Command="{Binding ItemCommand}" MouseAction="LeftClick"/>
</Border.InputBindings>
  • Related