如何设置 WPF 扩展器标题的样式?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/661503/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 20:09:38  来源:igfitidea点击:

How to style a WPF Expander Header?

wpfheaderstylesexpander

提问by Vasile Tomoiaga

I would like to apply a style on a WPF Expander Header. In the following XAML I have an Expander but the style is for all of it not just for the header.

我想在 WPF 扩展器标题上应用样式。在下面的 XAML 中,我有一个扩展器,但样式不仅适用于标题,而且适用于所有内容。

Thanks.

谢谢。

<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>

回答by Vasile Tomoiaga

I have combined some XAML from Josh Smithand MSDNand came up with a solution. Indeed, the control (al least the header) must be retemplated.

我结合了Josh SmithMSDN 的一些 XAML并提出了一个解决方案。实际上,必须重新设计控件(至少是标题)。

<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>

回答by PatrickV

I think Vasile's answer is on the right track, but it seems like it does a lot more than the original poster needed. All the original question was asking to do was to change the background of the header. While the change presented does do that, it also does other things.

我认为 Vasile 的答案是正确的,但它似乎比原始海报所需的要多得多。最初的问题要求做的就是更改标题的背景。虽然呈现的更改确实做到了这一点,但它也做了其他事情。

One of these other things is to replace the default implementation, I believe a ContentPresenter, with a TextBlock. So what happens when later we change our Expander so that the header is more complicated? Maybe something like:

其他事情之一是用 TextBlock 替换默认实现,我相信是 ContentPresenter。那么当稍后我们更改我们的 Expander 使标题更加复杂时会发生什么?也许是这样的:

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

I don't know, but it's not good. Instead, I think we want to keep this simple.

我不知道,但这并不好。相反,我认为我们希望保持简单。

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

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

That way when someone puts something that is not just text in our styled expander, we don't break. If you want to make sure you wrap the entirety of what they do with this background, which is probably desired, that would look like:

这样,当有人在我们的样式扩展器中放入不只是文本的内容时,我们就不会中断。如果你想确保你用这个背景来包装他们所做的全部事情,这可能是需要的,那看起来像:

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

回答by Dominic Hopton

Depends what you want to style -- you can style any part of it. If you want to change the content in the header, just place all your UI in the Expander.Header property, and it'll show in the header area.

取决于你想设计什么风格——你可以设计它的任何部分。如果您想更改标题中的内容,只需将所有 UI 放在 Expander.Header 属性中,它就会显示在标题区域中。

if that does't meet your needs, you probably need to re-template the control. Take a look at the control templates shipped in WPF here

如果这不能满足您的需求,您可能需要重新模板化控件。在此处查看WPF 中提供的控件模板