WPF 自定义控件组框 - 空 Header

WPF Custom Control GroupBox - Empty Header

我正在尝试实施一个自定义控件库项目以用于其他项目。我已经完成了 99%,并且一切正常,但是,我的自定义组框控件很挑剔,没有删除 header 间距来创建无缝框。以下是 Generic.xaml

中样式的 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>

样式主要是我拉出并删除 OpacityMask 以摆脱 header space 的默认 GroupBox 实现。此方法 100% 适用于所有本地项目并包含在资源字典中的基本项目。但是,既然我有一个引用我的自定义组框项目样式的外部项目,它就会消失。组框呈现,但是,header space 未被删除。

这是我的自定义控件的 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)));
        }
    }
}

我注释掉了 DefaultStyleKeyProperty 内容,因为启用它后我的控件将不再显示。我觉得这可能是问题的一部分?但是,如果我保留它,那么整个组框就不会显示。

MainWindow 在引用自定义控件项目的单独项目中

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

当您在 class 的静态构造函数中调用 DefaultStyleKeyProperty.OverrideMetadata 时,您应该为名为 generic.xamlResourceDictionary 中的控件定义默认样式它位于项目根目录下名为 themes 的文件夹中,默认情况下定义了控件 class。

如果您还没有这样做,请移动您的样式 themes/generic.xaml,并从 Style:

中删除 x:Key
 <Style TargetType="{x:Type local:GroupBoxNoHeader}">
 ...
   

如果您随后像这样定义自定义控件,则应始终应用您的样式,前提是您未设置或以其他方式覆盖应用中其他地方的控件实例的 Style 属性 :

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