web-dev-qa-db-fra.com

Comment styliser un en-tête WPF Expander?

Je voudrais appliquer un style sur un en-tête WPF Expander. Dans le XAML suivant, j'ai un Expander mais le style n'est pas seulement pour l'en-tête.

Merci.

<Page
xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
Width="640"
>
    <StackPanel>
        <StackPanel.Resources>
            <Style TargetType="Expander">
                <Style.Resources>
                    <LinearGradientBrush x:Key="BackBrush" StartPoint="0.5,0" EndPoint="0.5,1">
                        <GradientStop Color="#EF3132" Offset="0.1" />
                        <GradientStop Color="#D62B2B" Offset="0.9" />
                    </LinearGradientBrush>
                </Style.Resources>
                <Setter Property="Background" Value="{StaticResource BackBrush}"/>
            </Style>
        </StackPanel.Resources>
        <Expander>
            <StackPanel>
                <TextBlock>Bike</TextBlock>
                <TextBlock>Car</TextBlock>
                <TextBlock>Truck</TextBlock>
            </StackPanel>
        </Expander>
    </StackPanel>
</Page>
50
Vasile Tomoiaga

J'ai combiné du XAML de Josh Smith et MSDN et j'ai trouvé une solution. En effet, le contrôle (au moins l'en-tête) doit être remodelé.

<Page
xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
Width="400">
    <StackPanel>
        <StackPanel.Resources>

            <Style TargetType="Border" x:Key="RacePitBorderStyle" >
                <Style.Resources>
                    <LinearGradientBrush x:Key="BackBrush" StartPoint="0.5,0" EndPoint="0.5,1">
                        <GradientStop Color="#EF3132" Offset="0.1" />
                        <GradientStop Color="#D62B2B" Offset="0.9" />
                    </LinearGradientBrush>
                </Style.Resources>
                <Setter Property="Background" Value="{StaticResource BackBrush}"/>
            </Style>

            <DataTemplate x:Key="titleText">
                <Border Style="{StaticResource RacePitBorderStyle}" Height="24">
                    <TextBlock Text="{Binding}" 
                        Margin="4 0"
                        VerticalAlignment="Center"
                        Foreground="White"
                        FontSize="11" 
                        FontWeight="Normal"
                        Width="{Binding
                        RelativeSource={RelativeSource
                        Mode=FindAncestor,
                        AncestorType={x:Type Expander}},
                        Path=ActualWidth}"
                        TextWrapping="Wrap"/>
                </Border>
            </DataTemplate>

            <Style TargetType="{x:Type Expander}">
                <Setter Property="HeaderTemplate" Value="{StaticResource titleText}"/>
            </Style>

        </StackPanel.Resources>

        <Expander Name="hcontCtrl" Header="This is the header.">
            <StackPanel>
                <TextBox>This is a textbox</TextBox>
                <Button>A button</Button>
            </StackPanel>
        </Expander>

    </StackPanel>
</Page>
53
Vasile Tomoiaga

Je pense que la réponse de Vasile est sur la bonne voie, mais il semble que cela fasse beaucoup plus que l'affiche originale nécessaire. Tout ce que la question initiale demandait était de changer l'arrière-plan de l'en-tête. Bien que le changement présenté le fasse, il fait aussi d'autres choses.

L'une de ces autres choses est de remplacer l'implémentation par défaut, je crois un ContentPresenter, par un TextBlock. Alors, que se passe-t-il lorsque plus tard nous ajoutons un deuxième expandeur à ce panneau de pile? Peut-être quelque chose comme:

<Expander>
    <Expander.Header>
        <StackPanel>
            <Border height="5" width="5" Foreground="Blue"/>
            <TextBlock>Ha!</TextBlock>
        </StackPanel>
    </Expander.Header>
</Expander>

Je ne sais pas, mais ce n'est pas bon. Au lieu de cela, je pense que nous voulons garder cela simple.

<DataTemplate x:Key="expanderHeader">
    <ContentPresenter
        Content={Binding}
        TextBlock.Background={StaticResource myBrush}/>
</DataTemplate>

<Style TargetType="Expander">
    <Setter Property="HeaderTemplate" Value="{StaticResource expanderHeader}"/>
</Style>

De cette façon, lorsque quelqu'un met quelque chose qui n'est pas seulement du texte dans notre expandeur de style, nous ne cassons pas. Si vous voulez vous assurer d'envelopper l'intégralité de ce qu'ils font avec cet arrière-plan, ce qui est probablement souhaité, cela ressemblerait à:

<DataTemplate x:Key="expanderHeader">
    <Border Background={StaticResource myBrush}>
        <ContentPresenter Content={Binding}/>
    </Border>
</DataTemplate>
15
PatrickV

Cela dépend de ce que vous voulez styliser - vous pouvez styliser n'importe quelle partie de celui-ci. Si vous souhaitez modifier le contenu dans l'en-tête, placez simplement toute votre interface utilisateur dans la propriété Expander.Header, et cela s'affichera dans la zone d'en-tête.

si cela ne répond pas à vos besoins, vous devrez probablement reformater le contrôle. Jetez un œil aux modèles de contrôle livrés dans WPF ici

6
Dominic Hopton