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.xaml
的 ResourceDictionary
中的控件定义默认样式它位于项目根目录下名为 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)));
}
}
我正在尝试实施一个自定义控件库项目以用于其他项目。我已经完成了 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.xaml
的 ResourceDictionary
中的控件定义默认样式它位于项目根目录下名为 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)));
}
}