我想知道是否有办法将wpf样式的basedOn属性与dynamicresources一起使用。 e.g。
<Style BasedOn="{DynamicResource somestyle}">
<Setter Property="SomeProp" Value="SomeValue"/>
</Style>
这个例如抛出一个错误,指示无法使用dynamicresources和BasedOn样式。
我想知道有人能做到这一点吗?
感谢
答案 0 :(得分:15)
我认为主要原因是密封物体。如果您有样式层次结构:
Style A
/ \
Style A1 Style A2
这可能不是一个困难的场景。您使用动态资源引用StyleA
,因此每当该资源发生变化时,Style A1
和Style A2
都应更改其BasedOn
属性。但是,一旦在您的应用程序中使用Style,它就会变成一个密封的对象。 Style A
变得不可变。
您可以使用的一种解决方法是:
Style A
需要改变。 Style A
资源。Style A1
和Style A2
的新版本。您需要编写一份复制程序,复制所有Setters
,Resources
等。将BasedOn
设置为Style A
的新版本。 {DynamicResource StyleA1}
和{DynamicResource StyleA2}
现在应该了解这些资源发生变化(从第4步开始)并自动更新任何引用。
请注意,这是一个非常简单的场景。真实世界风格的层次结构可能更复杂,特别是如果它们分布在多个文件中并来自合并的字典。
希望我理解你的问题并帮助我们。
答案 1 :(得分:14)
我发现,由于您无法在BasedOn
上使用DynamicResource
,因此您可以通过合并{{1}将DynamicResource
“转换”为StaticResource
将“父”资源保存到当前的Window / UserControl /等等。这样,您现在可以使用ResourceDictionary
引用资源对象(例如Style
)。这样,您就可以StaticResource
使用Datatriggers
(通过转化)。
示例:
DynamicResource
因此,<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/MyProject.Styles;component/ButtonStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
[*Your other resources can be put here*]
</ResourceDictionary>
</Window.Resources>
...
<Button Command="{Binding MyCommandInViewModel, RelativeSource={RelativeSource AncestorType=Window}}">
<Button.Style>
<Style BasedOn="{StaticResource StyleFromButtonStyles}" TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding SomeBool}" Value="True">
<Setter Property="Button.Content" Value="{StaticResource SomeImage}"/>
</DataTrigger>
<DataTrigger Binding="{Binding SomeBool}" Value="False">
<Setter Property="Button.Content" Value="{StaticResource SomeOtherImage}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
会应用于导入的Datatriggers
设置的按钮。
希望这有帮助!