2010-02-19 72 views
1

我想在运行时动态更新默认的Window样式,以便在运行时动态更改FontSize和FontFamily。我发现,在你的资源字典样式在运行时密封的,不能改变的,所以我用更新的款式下面的方法:WPF在运行时更新样式

<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; 
} 

有几种这种方法存在问题,我有几个问题,为什么事情是这样的。

  1. 为什么样式在运行时是密封的,并且有一种使它们开启的方法?
  2. 当我重新添加新样式时,为什么我的所有窗口都没有拾取?为什么我必须手动将它应用到每个窗口?
  3. 有没有更好的方法?

回答

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,它将更新DynamicResource将拾取的Style并相应地更改Window属性。

看起来像很多工作,但它给你一些很好的灵活性,所有的“繁重工作”纯粹使用绑定完成。我们在当前正在处理的项目中使用了类似的技术,所以当用户选择填充/笔触颜色时,工具栏中的各种工具会进行更新以反映新值。

+0

+1至少手动的方法我到目前为止看到,欢呼! – kallotec 2014-05-02 02:05:56