简体   繁体   中英

WPF Custom Control GroupBox - Empty Header

I'm trying to implement a Custom Control library project to be utilized in other projects. I'm 99% there and everything is mostly working, however, my custom Group Box control is being picky and not removing the header spacing to create a seamless box. Below is the XAML for the styling in Generic.xaml

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WPFCommonControls">
    <Style x:Key="GroupBoxStyleNoHeader" TargetType="{x:Type local:GroupBoxNoHeader}">
        <Setter Property="BorderBrush" Value="#D5DFE5"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:GroupBoxNoHeader}">
                    <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 Background="{TemplateBinding Background}" BorderBrush="Transparent" BorderThickness="{TemplateBinding BorderThickness}"  Grid.Column="0" Grid.ColumnSpan="4" Grid.RowSpan="3" Grid.Row="1"/>
                        <Border BorderBrush="White" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="4" Grid.ColumnSpan="4" Grid.RowSpan="3" Grid.Row="1">
                            <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                                <Border BorderBrush="White" BorderThickness="{TemplateBinding BorderThickness}"/>
                            </Border>
                        </Border>
                        <Border x:Name="Header" Grid.Column="1" Padding="3,1,0,0" Grid.RowSpan="2" Grid.Row="0">
                            <ContentPresenter ContentSource="Header" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </Border>
                        <ContentPresenter Grid.Column="1" Grid.ColumnSpan="2" Margin="{TemplateBinding Padding}" Grid.Row="2" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

The style is mainly just the default GroupBox implementation that I pulled out and removed the OpacityMask in order to get rid of the header space. This method works 100% on a basic project where this is all local and contained in the a resource dictionary. However, now that I have an exterior project referencing my Custom Group Box project style, it's wigging out. The groupbox renders, however, the header space is not removed.

Here's my Custom Control's cs:

namespace WPFCommonControls
{
    /// <summary>
    /// Follow steps 1a or 1b and then 2 to use this custom control in a XAML file.
    ///
    /// Step 1a) Using this custom control in a XAML file that exists in the current project.
    /// Add this XmlNamespace attribute to the root element of the markup file where it is 
    /// to be used:
    ///
    ///     xmlns:MyNamespace="clr-namespace:WPFCommonControls"
    ///
    ///
    /// Step 1b) Using this custom control in a XAML file that exists in a different project.
    /// Add this XmlNamespace attribute to the root element of the markup file where it is 
    /// to be used:
    ///
    ///     xmlns:MyNamespace="clr-namespace:WPFCommonControls;assembly=WPFCommonControls"
    ///
    /// You will also need to add a project reference from the project where the XAML file lives
    /// to this project and Rebuild to avoid compilation errors:
    ///
    ///     Right click on the target project in the Solution Explorer and
    ///     "Add Reference"->"Projects"->[Select this project]
    ///
    ///
    /// Step 2)
    /// Go ahead and use your control in the XAML file.
    ///
    ///     <MyNamespace:GroupBoxNoHeader/>
    ///
    /// </summary>
    public class GroupBoxNoHeader : GroupBox
    {
        static GroupBoxNoHeader()
        {
            //DefaultStyleKeyProperty.OverrideMetadata(typeof(GroupBoxNoHeader), new FrameworkPropertyMetadata(typeof(GroupBoxNoHeader)));
        }
    }
}

I commented out the DefaultStyleKeyProperty stuff since my control would no longer show up with it enabled. I feel like this may be part of the issue? However, if I keep it in, then the whole group box doesn't show up.

MainWindow in separate project that references the Custom Control project

<Window x:Class="TestWpfResources.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:CommonControls="clr-namespace:WPFCommonControls;assembly=WPFCommonControls"
        xmlns:local="clr-namespace:TestWpfResources"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <Grid>
        <CommonControls:GroupBoxNoHeader Margin="30,30,30,30">
        </CommonControls:GroupBoxNoHeader>
    </Grid>
</Window>

When you call DefaultStyleKeyProperty.OverrideMetadata in the static constructor of your class, your're supposed to define a default style for the control in a ResourceDictionary called generic.xaml that is located in a folder called themes at the root of the project where the control class is defined by default.

So move your style themes/generic.xaml if you haven't already done so and also remove the x:Key from the Style :

 <Style TargetType="{x:Type local:GroupBoxNoHeader}">
 ...
   

If you then define your custom control like this, your style should always be applied assuming you don't set or otherwise override the Style property of the control instance somewhere else in your app:

public class GroupBoxNoHeader : GroupBox
{
    static GroupBoxNoHeader()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(GroupBoxNoHeader), 
            new FrameworkPropertyMetadata(typeof(GroupBoxNoHeader)));
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM