8

我在 WPF 应用程序的单独 dll 中有一个 BaseSkin 和多个 UserSkins。

根据谁在使用应用程序,基本皮肤和其中一个用户皮肤将合并到资源字典中并加载以供应用程序使用。

我的目标是能够在 BaseSkin 文件中指定样式,然后在特定的 UserSkin 文件上能够覆盖它,从而更改我需要的任何属性。

我知道我可以通过使用像这样的 BasedOn 属性来实现这一点:

根据:

<Style x:Key="ButtonBg" TargetType="{x:Type Button}">
    <Setter Property="Background" Value="Green"/>
</Style>

用户:

<Style x:Key="CustomButtonBg" TargetType="{x:Type Button}" BasedOn="{StaticResource ButtonBg}">
    <Setter Property="Background" Value="Blue"/>
</Style>

问题是现在元素必须有一个 CustomButtonBg 的样式,这实际上可能没有实现。有没有办法让两种样式使用相同的键(ButtonBg),当它们合并时,应用程序首先在 User 中查找名为 ButtonBg 的样式,如果不存在,则使用 base 中的样式?

我在想,如果我可以在 BasedOn 属性中给出程序集名称以指向 BaseSkin 文件,那么当我给它们相同的键时,我可以避免命名错误,但我找不到任何方法来做到这一点。其他选项是即使没有任何更改也只强制执行每种样式,或者在皮肤中以编程方式检查,但这些是最后的手段。

4

2 回答 2

11

您可以尝试利用资源查找逻辑。当 WPF 试图通过键查找资源时,它首先查找当前元素的ResourceDictionary,然后是其父元素,然后是该元素的父元素,依此类推。

因此,既然您说它对用户是有条件的,那么当您的原始基础ResourceDictionary处于该级别时,可以将其合并到该级别。WindowApplication

编辑:我有更好的信息。来自MSDN 上的合并字典

合并字典行为

合并字典中的资源在资源查找范围中占据一个位置,该位置位于它们合并到的主资源字典的范围之后。尽管资源键在任何单独的字典中必须是唯一的,但一个键可以在一组合并字典中多次存在。在这种情况下,返回的资源将来自在 MergedDictionaries 集合中按顺序找到的最后一个字典。如果 MergedDictionaries 集合是在 XAML 中定义的,则集合中合并字典的顺序是标记中提供的元素的顺序。如果在主字典和合并的字典中定义了键,则返回的资源将来自主字典。

这意味着您可以定义不同的 Base 皮肤ResourceDictionary并将其合并到另一个ResourceDictionary. 在后者中有 User 皮肤,它会先找到它,否则它将继续向下钻取到包含 Base 的合并字典。您的每个用户词典都可以合并基本词典,您只需将用户词典加载到应用程序中,而不是单独加载。

于 2009-07-30T20:38:36.827 回答
0

您可能只是将您的 Base 命名为 BaseButtonBg ,当您不合并基于用户的 ResourceDictionary 时,合并一个包含以下内容的通用名称:

<Style x:Key="ButtonBg" TargetType="{x:Type Button}" BasedOn="{StaticResource BaseButtonBg}"/>
于 2009-07-30T20:33:02.987 回答