2010-02-19 106 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