【发布时间】:2022-01-17 04:36:35
【问题描述】:
我有一个隐式的 WPF 控件样式(对于基于 MultiSelector 的控件)。我的问题是,只有当我将其全部定义为一种单一样式时,它才会被隐式拾取。如果我改为给它一个键,然后尝试基于 that 创建一个隐式版本,它就会停止工作。
为了说明这里的风格的缩写版本,当它工作时,所有作为一种隐式风格。 (该控件旨在在Canvas 上显示形状和图像,允许用户选择、操作它们等)
<Style TargetType="{x:Type ctrl:LayerView}" BasedOn="{StaticResource LayerViewStyle}">
<Style.Resources>
<!-- Any SdkLine object within the LayerView should use our custom LineControl -->
<DataTemplate DataType="{x:Type sdk:SdkLine}">
<ctrl:LineControl P1="{Binding P1}" P2="{Binding P2}"/>
</DataTemplate>
<!-- Any ItemsControl within the LayerView is presumed to use a Canvas -->
<Style TargetType="{x:Type ItemsControl}" >
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<Canvas IsItemsHost="True" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
</Style>
如果我像上面那样做,我所有的形状都会很漂亮;资源部分中的隐式样式被拾取。
这就是我打破它的方法:我给它一个键,然后让它隐含在下面一行。 (我不会重复整个风格。
<!-- Named version of full style -->
<Style x:Key="SpecialLayerViewStyle"
TargetType="{x:Type ctrl:LayerView}"
BasedOn="{StaticResource LayerViewStyle}">
... (rest of the above style here) ....
</Style
<Style TargetType="{x:Type ctrl:LayerView}" BasedOn="{StaticResource SpecialLayerViewStyle}"/>
突然之间,Resources 部分中的那些隐式样式都没有被拾取。没有其他变化。
第二个版本不应该与第一个版本具有相同的行为吗?我在这里缺少一些 WPF 样式/模板规则吗?
[编辑] 回答 cmets 中提出的问题:
该控件确实会覆盖元数据以使隐式样式起作用
static LayerView()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof(LayerView),
new FrameworkPropertyMetadata(typeof(LayerView)));
}
样式在控件旁边的资源字典中定义。该字典包含在任何尝试使用该控件的 XAML 代码中(在 <ResourceDictionary.MergedDictionaries> 部分中)。
当我进行更改(为之前的版本提供一个键,然后定义“隐式”版本)时,我将隐式版本紧挨着它放在同一个资源字典中。因此,之前看到隐式版本的任何 UI 也应该看到命名版本和新的隐式“基于”版本。
[/EDIT]
【问题讨论】:
-
您的控件是否具有设置默认样式键的静态构造函数?您如何尝试将样式应用于控件?样式和控件在哪里定义?请使用所有必要的详细信息更新您的问题。
-
我已编辑帖子以回答您的问题