【问题标题】:Implicit XAML Style stops working when I base it upon a Key-ed version当我基于 Key-ed 版本时,隐式 XAML 样式停止工作
【发布时间】: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 代码中(在 &lt;ResourceDictionary.MergedDictionaries&gt; 部分中)。

当我进行更改(为之前的版本提供一个键,然后定义“隐式”版本)时,我将隐式版本紧挨着它放在同一个资源字典中。因此,之前看到隐式版本的任何 UI 也应该看到命名版本和新的隐式“基于”版本。

[/EDIT]

【问题讨论】:

  • 您的控件是否具有设置默认样式键的静态构造函数?您如何尝试将样式应用于控件?样式和控件在哪里定义?请使用所有必要的详细信息更新您的问题。
  • 我已编辑帖子以回答您的问题

标签: wpf xaml


【解决方案1】:

当您定义一个调用DefaultStyleKeyProperty.OverrideMetadatastatic 构造函数时,您还应该在一个名为themes/generic.xaml 的资源字典中为您的自定义控件定义一个默认的Style

因此,在项目的根目录下创建一个名为“themes”的文件夹,并向其中添加名为“generic.xaml”的资源字典。然后在资源字典中定义控件的默认样式(不带任何x:Key):

<Style TargetType="{x:Type ctrl:LayerView}">
...
</Style>

您的控件的样式应该与任何其他控件的样式相同。

【讨论】:

  • 感谢您尝试帮助我。但是,我的隐式样式已经对使用它样式的控件的 XAML 可见。在我做出改变之前和之后都是如此。 WPF 拾取任何隐式样式,只要它是使用它样式的控件的可见 XAML。换句话说,不要求样式位于“themes”文件夹中专门命名为“generic.xaml”的字典中)。
  • 是的,否则它没有任何默认样式定义。删除静态构造函数或向themes/generic.xaml 添加默认样式。您当前的设置无效。
  • 很抱歉,它确实根据定义具有默认样式。通过包含的资源字典,我对控件的所有使用都清晰可见。这就是默认样式以前起作用的原因。我没有改变任何东西的位置。我所做的只是使默认样式基于键控
  • 没有。默认样式和隐式样式是有区别的。
  • 我最初在这里写道,“有什么区别?”但是(在我想到有一个叫做谷歌的东西之后......)我现在意识到我偶然发现了一个我以前从未理解过的区别,而不是在多年的 WPF 中。我认为隐式与默认相同。我明白你现在在说什么。我有一些阅读要做。谢谢
猜你喜欢
  • 1970-01-01
  • 2020-04-16
  • 2018-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-27
  • 1970-01-01
  • 2021-03-13
相关资源
最近更新 更多