WPF无标题空间的GroupBox

22

很简单,我想要一个没有标题空间的GroupBox。

最接近的方式是使用边框,但是边框“默认情况下”与GroupBox的样式不同。

最简单的方法(最少的XAML /代码)获取所需的GroupBox是什么?

谢谢。

5个回答

21
如果你真的不想要边框,那么有以下两种解决方案:

(1) 在 Blend 中编辑模板:

  • 右键单击 GroupBox > 编辑模板 > 复制编辑 > 确定
  • 搜索部分

      <Border.OpacityMask>
           <MultiBinding Converter="{StaticResource BorderGapMaskConverter}" ConverterParameter="7">
                ......
           </MultiBinding>
      </Border.OpacityMask>
    
  • 删除此(上述提到的)部分...您刚刚移除了“间隙”

  • 如果您不设置标题(如示例中所示),则这将起作用。但是,如果您设置标题,它将出现在边框后面。因此,为了更正这个问题,请在刚刚删除的部分所包含的边框中设置Panel.ZIndex="-1"(它看起来像<Border BorderBrush="White" BorderThickness= ...

(2) 使用重复的GroupBox并水平翻转它,然后将它放置在原始GroupBox下面:

  • 将以下代码放置在您的GroupBox下方(假设您的GroupBox名称为'OriginalGroupbox')

 <GroupBox Header="" Focusable="False" Panel.ZIndex="-1" 
           Width="{Binding ActualWidth, ElementName=OriginalGroupbox}" 
           Height="{Binding ActualHeight, ElementName=OriginalGroupbox}" 
           IsEnabled="{Binding IsEnabled, ElementName=OriginalGroupbox}"
           RenderTransformOrigin="0.5,0.5">
           <GroupBox.RenderTransform>
                <ScaleTransform ScaleX="-1"/>
           </GroupBox.RenderTransform>
 </GroupBox>
  • 将这两个GroupBox都包含在一个Grid中,像这样:

    <Grid>
         <GroupBox x:Name="OriginalGroupbox" Header="Mihir" ...>
            ...
         </GroupBox>
         <GroupBox Header="" Width="{Binding ActualWidth, ElementName=OriginalGroupbox}" ...>
            ...
         </GroupBox>
    </Grid>
    

  • 谢谢!回复 #1 是正确的方式。我将模板封装在它自己的样式中,现在如果我有一个不需要标题的 GroupBox,我会应用那个样式。 - PBelanger
    @PBelanger,您能否复制粘贴一下代码,展示一下您是如何将模板封装在其样式中的? - mohits00691

    17

    您可以通过将边框设置为圆角和不同颜色来模拟分组框的样式。这是一个看起来非常接近GroupBox边框的边框:

    <Border BorderThickness="1" CornerRadius="4" Height="100" Width="100" Padding="5" BorderBrush="LightGray"><TextBlock>Border</TextBlock></Border>
    

    alt text http://img264.imageshack.us/img264/6748/borderm.png


    5
    我看到这个解决方案存在一个问题,即GroupBox控件的样式将根据加载的样式(如操作系统或在app.xaml中定义的其他样式等)而改变。但是按照这种方式设置边框属性将无法遵循这些样式。 - PBelanger
    #FF999999 似乎更适合 GroupBox 的默认边框。 - Grault

    9

    在Mihir Gokani的回答基础上,您可以更改默认模板,使用触发器将标题的填充更改为无填充,当标题为空或不存在时。

    在GroupBox上使用以下样式,应该可以解决问题。

    <BorderGapMaskConverter x:Key="BorderGapMaskConverter"/>
    <Style x:Key="GroupBoxStyle" 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"/>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="6"/>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="6"/>
                        </Grid.RowDefinitions>
                        <Border BorderBrush="Transparent" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="4" Grid.Column="0" CornerRadius="4" Grid.Row="1" Grid.RowSpan="3"/>
                        <Border x:Name="Header" Grid.Column="1" Padding="3,1,3,0" Grid.Row="0" Grid.RowSpan="2">
                            <ContentPresenter ContentSource="Header" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </Border>
                        <ContentPresenter Grid.ColumnSpan="2" Grid.Column="1" Margin="{TemplateBinding Padding}" Grid.Row="2" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        <Border BorderBrush="White" BorderThickness="{TemplateBinding BorderThickness}" Grid.ColumnSpan="4" CornerRadius="4" Grid.Row="1" Grid.RowSpan="3">
                            <Border.OpacityMask>
                                <MultiBinding ConverterParameter="7" Converter="{StaticResource BorderGapMaskConverter}">
                                    <Binding ElementName="Header" Path="ActualWidth"/>
                                    <Binding Path="ActualWidth" RelativeSource="{RelativeSource Self}"/>
                                    <Binding Path="ActualHeight" RelativeSource="{RelativeSource Self}"/>
                                </MultiBinding>
                            </Border.OpacityMask>
                            <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="3">
                                <Border BorderBrush="White" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2"/>
                            </Border>
                        </Border>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="Header" Value="{x:Null}">
                            <Setter TargetName="Header" Property="Padding" Value="0" />                                 
                        </Trigger>
                            <Trigger Property="Header" Value="">
                                <Setter TargetName="Header" Property="Padding" Value="0" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    

    请注意,唯一的添加是:
    <ControlTemplate.Triggers>
        <Trigger Property="Header" Value="{x:Null}">
            <Setter TargetName="Header" Property="Padding" Value="0" />                                 
        </Trigger>
        <Trigger Property="Header" Value="">
            <Setter TargetName="Header" Property="Padding" Value="0" />
        </Trigger>
    </ControlTemplate.Triggers>
    

    你也可以将可见性设置为折叠,因为我猜这更符合你想要表达的触发器。 - DerApe

    1
    整个代码和使用演示的完整内容。
    <UserControl.Resources>
        <ResourceDictionary>
            <BorderGapMaskConverter x:Key="BorderGapMaskConverter"/>
        <Style x:Key="GroupBoxStyle1" 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"/>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="6"/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="*"/>
                                <RowDefinition Height="6"/>
                            </Grid.RowDefinitions>
                            <Border BorderBrush="Transparent" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="4" Grid.Column="0" CornerRadius="4" Grid.Row="1" Grid.RowSpan="3"/>
                            <Border BorderBrush="White" BorderThickness="{TemplateBinding BorderThickness}" Grid.ColumnSpan="4" CornerRadius="4" Grid.Row="1" Grid.RowSpan="3">
    
                                <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="3">
                                    <Border BorderBrush="White" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2"/>
                                </Border>
                            </Border>
                            <Border x:Name="Header" Grid.Column="1" Padding="3,1,3,0" Grid.Row="0" Grid.RowSpan="2">
                                <ContentPresenter ContentSource="Header" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                            </Border>
                            <ContentPresenter Grid.ColumnSpan="2" Grid.Column="1" Margin="{TemplateBinding Padding}" Grid.Row="2" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
            </ResourceDictionary>
    </UserControl.Resources>
    
    <Grid>
    
        <GroupBox Header="" HorizontalAlignment="Left" Margin="70,39,0,0" VerticalAlignment="Top" Height="169.96" Width="299.697" Style="{DynamicResource GroupBoxStyle1}"/>
    </Grid>
    


    0

    我正在寻找类似的解决方案。我需要一种分组框样式,其中边框仅在没有标题文本时关闭。

    我并不确定这是最好的解决方案,但它可以正常工作...

    我们有一个转换器(目前仅适用于文本):

    public class GroupBoxHeaderVisibilityConverter : IMultiValueConverter
    {
        #region IMultiValueConverter Members
    
        public object Convert(object[] values, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            ContentPresenter header = values[0] as ContentPresenter;
            if (header != null)
            {
                string text = header.Content as string;
                if (string.IsNullOrEmpty(text))
                {
                    return 0.0;
                }
            }
            return values[1];
        }
    
        public object[] ConvertBack(object value, System.Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new System.NotImplementedException();
        }
    
        #endregion
    }
    

    以及对GroupBox样式的修改:

    <Border
        x:Name="Header"
        Grid.Column="1"
        Grid.Row="0"
        Grid.RowSpan="2"
        Padding="3,1,3,0">
        <Border.Tag>
            <MultiBinding Converter="{StaticResource GroupBoxHeaderVisibilityConverter}">
                <Binding Path="Content" ElementName="groupBoxLabel" />
                <Binding Path="ActualWidth" RelativeSource="{RelativeSource Self}" />
            </MultiBinding> 
        </Border.Tag>
        <Label x:Name="groupBoxLabel"
            FontSize="{StaticResource Fonts_SmallFontSize}"
            Foreground="{TemplateBinding Foreground}">
            <ContentPresenter
                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                ContentSource="Header"
                RecognizesAccessKey="True" />
        </Label>
    </Border>
    <ContentPresenter
        Margin="{TemplateBinding Padding}"
        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
        Grid.Column="1"
        Grid.ColumnSpan="2"
        Grid.Row="2" />
    <Border
        Grid.ColumnSpan="4"
        Grid.Row="1"
        Grid.RowSpan="3"
        BorderBrush="Transparent"
        BorderThickness="{TemplateBinding BorderThickness}"
        CornerRadius="4">
        <Border.OpacityMask>                                
            <MultiBinding
                Converter="{StaticResource BorderGapMaskConverter}"
                ConverterParameter="7">
                <Binding ElementName="Header" Path="Tag" />
                <Binding
                    Path="ActualWidth"
                    RelativeSource="{RelativeSource Self}" />
                <Binding
                    Path="ActualHeight"
                    RelativeSource="{RelativeSource Self}" />
            </MultiBinding>
        </Border.OpacityMask>
        <Border
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}"
            CornerRadius="3" />
    </Border>
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接