如何在 GroupBox header 中换行文本?

How to wrap text in GroupBox header?

如何在 GroupBox 中换行 header?此代码无效。

<GroupBox>
<GroupBox.Header>
    <TextBlock Text="qwertyuiopasdfghjklqwertyuiopasdfghjkl" TextWrapping="Wrap"/>
</GroupBox.Header>

为了让文本内容换行,您必须指定 width,否则 textblock 会自动设置为文本块中内容的长度。

   <TextBlock Width="150" Text="qwertyuiopasdfghjklqwertyuiopasdfghjkl" TextWrapping="Wrap"/>

虽然通过显式指定值或与另一个元素绑定来设置 header 的宽度的解决方案非常有效,但深入研究 GroupBox 的默认样式,我发现对样式进行小的修改将解决这个问题。

<BorderGapMaskConverter x:Key="BorderGapMaskConverter"/>

<Style TargetType="{x:Type GroupBox}">
    <Setter Property="BorderBrush" Value="#D5DFE5"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type GroupBox}">
                <Grid SnapsToDevicePixels="True">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="6"/>
                        <!-- <ColumnDefinition Width="Auto"/> is removed because its Width="Auto" is problematic. -->
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="6"/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                        <RowDefinition Height="6"/>
                    </Grid.RowDefinitions>
                    <!-- The value of Grid.ColumnSpan is changed from 4 to 3. -->
                    <Border Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="1" Grid.RowSpan="3"
                            BorderBrush="Transparent"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            Background="{TemplateBinding Background}"
                            CornerRadius="4"/>
                    <!-- The value of Grid.ColumnSpan is changed from 4 to 3. -->
                    <Border Grid.ColumnSpan="3" Grid.Row="1" Grid.RowSpan="3"
                            BorderBrush="White"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            CornerRadius="4">
                        <Border.OpacityMask>
                            <MultiBinding Converter="{StaticResource BorderGapMaskConverter}"
                                          ConverterParameter="7">
                                <Binding ElementName="Header" Path="ActualWidth"/>
                                <Binding RelativeSource="{RelativeSource Self}" Path="ActualWidth"/>
                                <Binding RelativeSource="{RelativeSource Self}" Path="ActualHeight"/>
                            </MultiBinding>
                        </Border.OpacityMask>
                        <Border BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                CornerRadius="3">
                            <Border BorderBrush="White"
                                    BorderThickness="{TemplateBinding BorderThickness}"
                                    CornerRadius="2"/>
                        </Border>
                    </Border>
                    <!-- HorizontalAlignment="Left" is added to adjust the surrounding line. -->
                    <Border x:Name="Header"
                            Grid.Column="1" Grid.Row="0" Grid.RowSpan="2"
                            HorizontalAlignment="Left"
                            Padding="3,1,3,0">
                        <ContentPresenter ContentSource="Header"
                                          RecognizesAccessKey="True"
                                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    </Border>
                    <!-- Grid.ColumnSpan="2" is removed because it is no longer necessary. -->
                    <ContentPresenter Grid.Column="1" Grid.Row="2"
                                      Margin="{TemplateBinding Padding}"
                                      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

此问题的根本原因是 Grid 的第二个 ColumnDefinition Width="Auto"。因此删除 ColumnDefinition,以便将 header 的 Border 分配给原始的第 3 个 ColumnDefinition。然后将 HorizontalAlignment="Left" 添加到 header 的边框。 ColumnSpan 的一些微不足道的编辑。就是这样。

此修改后的样式让 WPF 的布局引擎根据 GroupBox 的实际宽度自动确定 header 的宽度。无需每次都关心宽度。据我所知,默认的没有明显的退化。