扩展/覆盖资源字典中的样式

Bra*_*don 7 c# wpf xaml resourcedictionary

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

根据使用应用程序的用户,基础外观和其中一个用户外观将合并到资源字典中并加载以供应用程序使用.

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

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

基础:

<Style x:Key="ButtonBg" TargetType="{x:Type Button}">
    <Setter Property="Background" Value="Green"/>
</Style>
Run Code Online (Sandbox Code Playgroud)

用户:

<Style x:Key="CustomButtonBg" TargetType="{x:Type Button}" BasedOn="{StaticResource ButtonBg}">
    <Setter Property="Background" Value="Blue"/>
</Style>
Run Code Online (Sandbox Code Playgroud)

问题是现在元素必须具有StyleButtonBg样式,实际上可能无法实现.有没有办法让两个样式使用相同的键(ButtonBg),并且当它们合并时,应用程序在User用户中查找名为ButtonBg的样式,如果不存在,请使用base中的样式?

我想如果我可以将BasedOn属性中的程序集名称指向BaseSkin文件,当我给它们相同的密钥时,我可以避免命名错误,但我找不到任何方法来做到这一点.其他选项只是强制执行每个样式,即使没有任何变化,或者在皮肤中以编程方式检查,但这些是最后的度假胜地.

Joe*_*ant 10

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

因此,既然你说它是有条件的用户,那么可以在你的原始基础处于关卡ResourceDictionaryWindow水平上合并Application.

编辑:我有更好的信息.来自合并词典的MSDN:

合并字典行为

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

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