我有一个控件PaneBase
,它派生自UserControl
。没有XAML,它只是一个控件。有问题的UserControl
类型是来自Catel的类型,但在使用System.Windows.Controls.UserControl
时我仍然会发现此问题。
public class PaneBase : UserControl
{
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title",
typeof(string),
typeof(PaneBase),
new PropertyMetadata(default(string)));
public string Title
{
get => (string) GetValue(TitleProperty);
set => SetValue(TitleProperty, value);
}
}
我有另一个控件EquationPane
,它派生自PaneBase
并且确实有XAML:
EquationPane.xaml
<local:PaneBase x:Class="EngineersToolkit.Windows.Views.Panes.EquationPane"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:catel="http://schemas.catelproject.com" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:EngineersToolkit.Windows.Views.Panes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="Equation"
d:DataContext="{d:DesignData EquationPaneViewModel}" d:DesignHeight="450" d:DesignWidth="800"
mc:Ignorable="d">
<Grid>
<TextBox Width="150" Height="30"
Text="{Binding Equation, Mode=TwoWay}" />
</Grid>
</local:PaneBase>
EquationPane.xaml.cs
public partial class EquationPane
{
public EquationPane()
{
InitializeComponent();
DataContext = new EquationPaneViewModel();
}
}
到目前为止,所有这些都有效,当我在窗口中包含EquationPane
时,它会正常显示:
<Grid>
<panes:EquationPane Width="100" Height="100"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Background="Aqua" />
</Grid>
如果我尝试设置控件的样式,它会继续正常工作:
<Style TargetType="{x:Type panes:EquationPane}">
<Setter Property="Background" Value="Red" />
</Style>
但是,如果我将样式定位到PaneBase
,事情就会开始崩溃。如果我将TargetType
更改为PaneBase,则不会应用该样式。但是,如果我在PaneBase
中覆盖依赖项属性元数据,如下所示:
static PaneBase()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(PaneBase),
new FrameworkPropertyMetadata(
typeof(PaneBase)));
}
然后控件停止渲染,留下一个空白窗口。为什么会这样?
答案 0 :(得分:1)
隐式样式不会自动应用于派生类型。要将PaneBase的样式应用于EquationPane,您可以执行以下操作之一:
1.在您的EquationPane.xaml.cs
上写下这个public EquationPane()
{
this.SetResourceReference(StyleProperty, typeof(PaneBase));
}
2.明确提供使用EquationPane的样式
<panes:EquationPane Style="{DynamicResource {x:Type PaneBase}}"/>
3.定义基于父样式的样式
<Style x:Key="{x:Type PaneBase}" TargetType="{x:Type PaneBase}">
<Setter Property="Background" Value="Red" />
</Style>
<Style TargetType="{x:Type panes:EquationPane}" BasedOn="{StaticResource {x:Type PaneBase}}"/>
答案 1 :(得分:1)
为什么会这样?
WPF控件“看起来很”,这意味着除非为它们定义模板,否则它们没有外观。
以下表示在PaneBase
中为themes/generic.xaml
定义了默认样式:
static PaneBase()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(PaneBase),
new FrameworkPropertyMetadata(
typeof(PaneBase)));
}
然后你应该定义这样一种风格:
<Style TargetType="local:PaneBase">
<Setter Property="Background" Value="Red" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type UserControl}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
如果删除PanelBase
中的静态构造函数,它将从UserControl
基类的样式继承模板。
如果您为此Style
定义PaneBase
,请执行以下操作:
<Style TargetType="{x:Type local:PaneBase}">
<Setter Property="Background" Value="Red" />
</Style>
...它不再有模板,这就是你在窗口中看不到控件的原因。