WPF 样式导致循环
为什么以下 XAML 会导致某些主题出现堆栈溢出异常?
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ExpressionLight.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style x:Key="BaseButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Margin" Value="5"/>
</Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource BaseButtonStyle}"/>
</ResourceDictionary>
</Application.Resources>
我尝试过在互联网上找到的几个主题,其中大约一半会导致异常。
是否有另一种方法可以将命名的 Style
应用为默认值?
编辑:
问题是主题
将默认样式添加到资源字典中(名为System.Windows.Control.Button
的条目) )。由于字典只能包含每个键的单个条目,因此不可能在同一资源字典中添加新的默认值。
不知道为什么它会导致“stackoverflow”而不是“重复键”异常。这可能是因为对可能包含重复键的合并字典进行了特殊处理。
解决方案是在代码中应用命名的 Style
作为默认值:
void AppStartup(object sender, StartupEventArgs args) {
this.Resources[typeof(Button)] = this.Resources["BaseButtonStyle"];
....
}
由于 BaseButtonStyle
静态绑定到主题,因此当然不可能使用此解决方案在运行时更改主题。
Why does the following XAML cause a stack overflow exception with some themes?
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ExpressionLight.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style x:Key="BaseButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Margin" Value="5"/>
</Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource BaseButtonStyle}"/>
</ResourceDictionary>
</Application.Resources>
I have tried several themes found on internet and about half of them causes the exception.
Is there another way to apply a named Style
as default?
Edit:
The problem is that the Theme
adds the default style to the resource dictionary (an entry with the name System.Windows.Control.Button
). Since a dictionary can only contain a single entry for each key it is not possible add a new default within the same resource dictionary.
Don't know why it leads to a "stackoverflow" instead of a "duplicate key" exception. It is probably because of the special handling of merged dictionaries which can contain duplicate keys.
The solution is to apply the named Style
as default in code:
void AppStartup(object sender, StartupEventArgs args) {
this.Resources[typeof(Button)] = this.Resources["BaseButtonStyle"];
....
}
Since the BaseButtonStyle
is staticly bound to the theme it is of course not possible to change theme at runtime with this solution.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您在此代码中存在循环依赖关系:
此样式表示它适用于 TargetType Button,这很好。
它还说它是基于为 TargetType Button 定义的 Style,这就是 this 本身。
最好为之前的样式分配一个键,然后在 BasedOn 中使用该键。
编辑:
再次查看您的代码后,您的样式与 ExpressionLight.xaml 中定义的样式之间似乎存在循环引用。解决方法是将资源放置在不同级别。
you are having circular dependency in this code:
this style says that it is for TargetType Button, thats fine.
it also says that it is BasedOn the Style defined for TargetType Button, which is this itself.
Better to assign a key to the previous Style and then use that key in BasedOn.
EDIT:
After going through your code again it seems that there is a circular reference between your style and the style defined in ExpressionLight.xaml. A workaround would be to place resources at different levels.