【问题标题】:How to style a WPF Expander Header?如何设置 WPF 扩展器标题的样式?
【发布时间】:2010-10-14 06:34:33
【问题描述】:

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

谢谢。

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

【问题讨论】:

    标签: wpf header styles expander


    【解决方案1】:

    我结合了来自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>
    

    【讨论】:

    • 我发现让扩展器宽度成为一个真正的问题,而您的代码就是这样做的。它可以在 xamlpad 中完美运行。但是在我的代码中它不会并导致可怕的图形滞后。 Width="{Binding RelativeSource{RelativeSource Mode=FindAncestor,AncestorType={x:Type Expander}}, Path=ActualWidth}"> 通过添加上述内容,它可以工作,但会滞后。如果我删除它,或者更改 Path=Width,它就不起作用并且延迟消失了。
    • 正是我所需要的。谢谢!有时深入研究 XAML 会让人头疼。
    • 我建议删除样式并直接在扩展器上使用 'HeaderTemplate' 属性。这样可以保留您的默认样式。
    • 这种样式在数据网格分组标题上看起来不错,但它占用了大量资源。使用此样式后,单击数据网格行和选择它的那一刻后,我得到了 1 秒的延迟。没有这种风格,一切都会很快。我的数据网格中只有 300 行。
    【解决方案2】:

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

    其中之一是用 TextBlock 替换默认实现,我相信 ContentPresenter。那么当我们稍后更改 Expander 以使标头更复杂时会发生什么?可能是这样的:

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

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

    <DataTemplate x:Key="expanderHeader">
        <ContentPresenter
            Content={Binding}
            TextBlock.Background={StaticResource myBrush}/>
    </DataTemplate>
    
    <Style TargetType="Expander">
        <Setter Property="HeaderTemplate" Value="{StaticResource expanderHeader}"/>
    </Style>
    

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

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

    【讨论】:

      【解决方案3】:

      取决于你想要的样式——你可以设置它的任何部分。如果你想改变标题中的内容,只需将你所有的 UI 放在 Expander.Header 属性中,它就会显示在标题区域中。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-02-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-18
        • 1970-01-01
        相关资源
        最近更新 更多