WPF GroupBox Header Customization

佐手、 提交于 2019-12-01 10:58:35

I had to do something similar some time ago, I wanted to create a GroupBox with two headers (one on the left and one on the right). I just used Reflector to get the code for BorderGapMaskConverter, and modified it to create my own converter. You could probably do the same here.


EDIT: I modified my converter to make it work for a centered header.

Here's the ControlTemplate

<ControlTemplate TargetType="{x:Type GroupBox}">
    <Grid SnapsToDevicePixels="true">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="6"/>
            <ColumnDefinition Width="*"/>
            <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 CornerRadius="4"
            Grid.Row="1"
            Grid.RowSpan="3"
            Grid.Column="0"
            Grid.ColumnSpan="5"
            BorderThickness="{TemplateBinding BorderThickness}"
            BorderBrush="Transparent"
            Background="{TemplateBinding Background}"/>
        <Border x:Name="Header"
            Padding="3,1,3,0"
            Grid.Row="0"
            Grid.RowSpan="2"
            Grid.Column="2">
            <ContentPresenter ContentSource="Header" 
                          RecognizesAccessKey="True" 
                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
        </Border>
        <ContentPresenter Grid.Row="2"
                      Grid.Column="1"
                      Grid.ColumnSpan="3"
                      Margin="{TemplateBinding Padding}"
                      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
        <Border CornerRadius="4"
            Grid.Row="1"
            Grid.RowSpan="3"
            Grid.ColumnSpan="5"
            BorderThickness="{TemplateBinding BorderThickness}"
            BorderBrush="White">
            <Border.OpacityMask>
                <MultiBinding Converter="{StaticResource CenterBorderGapMaskConverter}">
                    <Binding ElementName="Header"
                         Path="ActualWidth"/>
                    <Binding RelativeSource="{RelativeSource Self}"
                         Path="ActualWidth"/>
                    <Binding RelativeSource="{RelativeSource Self}"
                         Path="ActualHeight"/>
                </MultiBinding>
            </Border.OpacityMask>

            <Border BorderThickness="{TemplateBinding BorderThickness}"
                BorderBrush="{TemplateBinding BorderBrush}"
                CornerRadius="3">
                <Border BorderThickness="{TemplateBinding BorderThickness}"
                    BorderBrush="White"
                    CornerRadius="2"/>
            </Border>
        </Border>
    </Grid>
</ControlTemplate>

And here's the converter:

class CenterBorderGapMaskConverter : IMultiValueConverter
{
    // Methods
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        Type type = typeof(double);
        if (values == null
            || values.Length != 3
            || values[0] == null
            || values[1] == null
            || values[2] == null
            || !type.IsAssignableFrom(values[0].GetType())
            || !type.IsAssignableFrom(values[1].GetType())
            || !type.IsAssignableFrom(values[2].GetType()))
        {
            return DependencyProperty.UnsetValue;
        }

        double pixels = (double)values[0];
        double width = (double)values[1];
        double height = (double)values[2];
        if ((width == 0.0) || (height == 0.0))
        {
            return null;
        }
        Grid visual = new Grid();
        visual.Width = width;
        visual.Height = height;
        ColumnDefinition colDefinition1 = new ColumnDefinition();
        ColumnDefinition colDefinition2 = new ColumnDefinition();
        ColumnDefinition colDefinition3 = new ColumnDefinition();
        colDefinition1.Width = new GridLength(1.0, GridUnitType.Star);
        colDefinition2.Width = new GridLength(pixels);
        colDefinition3.Width = new GridLength(1.0, GridUnitType.Star);
        visual.ColumnDefinitions.Add(colDefinition1);
        visual.ColumnDefinitions.Add(colDefinition2);
        visual.ColumnDefinitions.Add(colDefinition3);
        RowDefinition rowDefinition1 = new RowDefinition();
        RowDefinition rowDefinition2 = new RowDefinition();
        rowDefinition1.Height = new GridLength(height / 2.0);
        rowDefinition2.Height = new GridLength(1.0, GridUnitType.Star);
        visual.RowDefinitions.Add(rowDefinition1);
        visual.RowDefinitions.Add(rowDefinition2);
        Rectangle rectangle1 = new Rectangle();
        Rectangle rectangle2 = new Rectangle();
        Rectangle rectangle3 = new Rectangle();
        rectangle1.Fill = Brushes.Black;
        rectangle2.Fill = Brushes.Black;
        rectangle3.Fill = Brushes.Black;
        Grid.SetRowSpan(rectangle1, 2);
        Grid.SetRow(rectangle1, 0);
        Grid.SetColumn(rectangle1, 0);
        Grid.SetRow(rectangle2, 1);
        Grid.SetColumn(rectangle2, 1);
        Grid.SetRowSpan(rectangle3, 2);
        Grid.SetRow(rectangle3, 0);
        Grid.SetColumn(rectangle3, 2);
        visual.Children.Add(rectangle1);
        visual.Children.Add(rectangle2);
        visual.Children.Add(rectangle3);
        return new VisualBrush(visual);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        return new object[] { Binding.DoNothing };
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!