我想在运行时动态更新默认的Window样式,这样我就可以在运行时动态更改FontSize和FontFamily。我发现资源字典中的样式在运行时是密封的,无法更改,因此我使用以下方法更新样式:
<Style TargetType="{x:Type Window}">
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="FontSize" Value="12pt"/>
</Style>
使用以下代码:
Style newStyle = (Make a copy of the old style but with the FontSize and FontFamily changed)
// Remove and re-add the style to the ResourceDictionary.
this.Resources.Remove(typeof(Window));
this.Resources.Add(typeof(Window), newStyle);
// The style does not update unless you set it on each window.
foreach (Window window in Application.Current.Windows)
{
window.Style = newStyle;
}
这种方法存在一些问题,我有几个问题,为什么事情就是这样。
答案 0 :(得分:3)
我可能会使用“设置服务”解决这个问题,该服务会公开各种设置的属性,并像正常绑定一样触发INPC。接下来,我将这种风格改为:
<Style x:Key="MyWindowStyle">
<Setter Property="FontFamily" Value="{Binding Path=FontFamily, Source={StaticResource SettingsService}, FallbackValue=Arial}"/>
<Setter Property="FontSize" Value="{Binding Path=FontSize, Source={StaticResource SettingsService}, FallbackValue=12}"/>
</Style>
将“设置服务”定义为静态资源:
<services:SettingsService x:Key="SettingsService"/>
然后在每个窗口中确保样式设置为DynamicResource:
<Window Style="{DynamicResource MyWindowStyle}" .... >
静态和动态资源之间的差异经常存在很多误解,但基本区别是静态是“一次性”设置,而动态会在资源发生变化时更新设置。
现在,如果您在“设置服务”中设置这些属性,它们将触发INPC,它将更新Style,DynamicResource将接收该样式并相应地更改Window属性。
看起来像很多工作,但它给你一些很好的灵活性,所有的“繁重”都是纯粹使用Bindings完成的。我们正在对我正在进行的项目使用类似的技术,因此当用户选择填充/描边颜色时,工具栏中的各种工具会更新以反映新值。