我在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>
问题是现在元素必须具有StyleButtonBg样式,实际上可能无法实现。有没有办法让两个样式使用相同的键(ButtonBg),并且当它们合并时,应用程序在User用户中查找名为ButtonBg的样式,如果不存在,请使用base中的样式? / p>
我在想,如果我可以将BasedOn属性中的程序集名称指向BaseSkin文件,那么当我给它们相同的密钥时,我可以避免命名错误,但我找不到任何方法来做到这一点。其他选项只是强制执行每个样式,即使没有任何改变,或者在皮肤中以编程方式检查,但这些是最后的度假。
答案 0 :(得分:10)
您可以尝试利用资源查找逻辑。当WPF尝试通过键查找资源时,它首先查看当前元素的ResourceDictionary
,然后查看其父元素,然后查看其父元素,依此类推。
因此,既然您说它是以用户为条件的,那么可以在ResourceDictionary
级Window
合并,而原始基数为Application
级。
编辑:我有更好的信息。来自MSDN on Merged Dictionaries:
合并字典行为
合并字典中的资源占用资源查找范围中的位置,该位置恰好位于它们合并到的主资源字典的范围之后。虽然资源键在任何单个字典中必须是唯一的,但是在一组合并的字典中,键可以存在多次。在这种情况下,返回的资源将来自MergedDictionaries集合中按顺序找到的最后一个字典。如果在XAML中定义了MergedDictionaries集合,则集合中合并的字典的顺序是标记中提供的元素的顺序。如果在主词典中以及在合并的词典中定义了键,则返回的资源将来自主词典。这些范围规则同样适用于静态资源引用和动态资源引用。
这意味着您可以在不同的ResourceDictionary
中定义Base皮肤,并将其合并到另一个ResourceDictionary
中。在后者中有User皮肤,它会先找到它,否则它将继续深入到包含Base的合并字典。您的每个用户词典都可以合并Base词典,您只需将用户词典加载到应用程序中,而不是单独加载。
答案 1 :(得分:0)
您可能只将Base命名为BaseButtonBg,当您不合并基于用户的ResourceDictionary时,合并一个包含以下内容的通用:
<Style x:Key="ButtonBg" TargetType="{x:Type Button}" BasedOn="{StaticResource BaseButtonBg}"/>