2013-11-15 131 views
2

我現在正在XAML基礎樣式中工作,其中包含我的標準HandledWindow類型的模板。 風格包括幾種本地資源,如顏色,字體和其他變量,以便在我的風格中重複使用。什麼是在WPF中創建UI設置的正確方法?

我正在考慮用戶的UI設置,所以他可以根據自己的意願更改顏色和大小等內容。 但是後來我發現改變本地資源不會改變風格本身,但只適用於當前的HandledWindow實例,所以它不適合UI設置,因爲在應用程序中可能會有更多的運行窗口。

然後我意識到我必須綁定變量相對於我的HandledWindow類的模板,這將包括所有可更改的設置作爲公共&靜態屬性。但後來我遇到了靜態屬性綁定的問題,因爲我無法提出僅適用於實例的PropertyChanged事件。而且窗口本身不會更新它的風格。

此外,我試圖讓樣式立即作出反應並立即更新,無需重新啓動。

+1

發佈相關代碼和XAML。順便說一句WPF有[內置支持主題](http://stackoverflow.com/a/11139598/643085),恐龍winforms完全沒有,這就是爲什麼你被迫在winforms各種可怕的黑客,而在WPF中,一切都美麗而快樂。 –

+0

主題技巧是通過替換'HandledWindow'的當前實例的資源完成的,我也在想這個,但是我需要一些能夠在數據綁定的同時改變其他窗口的主題,甚至不需要加載任何XAML頁面僅通過C#代碼,爲該屬性設置一個新值,並且可視化UI應該在同一時刻更新。我會在幾分鐘後發佈我的代碼。 請注意,這些靜態公共屬性也應該可以通過用戶界面進行編輯,這意味着應該有另一個數據綁定從UI進行設置。 – Lispwave

+1

否。如果您希望應用程序範圍的主題加載「System.Windows.Application.Current.Resources」中的資源字典。 –

回答

1

WPF是「以資源爲中心」的。您可以在資源中定義所有用戶界面樣式,畫筆和模板,並且在運行時可以很容易地啓用應用程序範圍內的主題更改,從而涵蓋您提到的所有屬性。下面是我如何做到這一點,我MainViewModel它通過其SettingsViewModel從我的設置窗口收到消息後:

private void ApplyTheme() 
{   
    Application.Current.Resources.MergedDictionaries.Clear(); 

    var rd = new ResourceDictionary { { "Locator", locator } }; 
    Application.Current.Resources.MergedDictionaries.Add(rd); 

    switch (theme) 
    { 
     case "Blue": 
      Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("/Telerik.Windows.Themes.Office_Blue;component/Themes/System.Windows.xaml", UriKind.RelativeOrAbsolute) }); 
      Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("/Telerik.Windows.Themes.Office_Blue;component/Themes/Telerik.Windows.Controls.GridView.xaml", UriKind.RelativeOrAbsolute) }); 
      Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("/Telerik.Windows.Themes.Office_Blue;component/Themes/Telerik.Windows.Controls.Input.xaml", UriKind.RelativeOrAbsolute) }); 
      Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("/Telerik.Windows.Themes.Office_Blue;component/Themes/Telerik.Windows.Controls.Navigation.xaml", UriKind.RelativeOrAbsolute) }); 
      Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("/Telerik.Windows.Themes.Office_Blue;component/Themes/Telerik.Windows.Controls.xaml", UriKind.RelativeOrAbsolute) }); 
      break; 
     case "Summer": 
      Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("/Telerik.Windows.Themes.Summer;component/Themes/System.Windows.xaml", UriKind.RelativeOrAbsolute) }); 
      Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("/Telerik.Windows.Themes.Summer;component/Themes/Telerik.Windows.Controls.GridView.xaml", UriKind.RelativeOrAbsolute) }); 
      Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("/Telerik.Windows.Themes.Summer;component/Themes/Telerik.Windows.Controls.Input.xaml", UriKind.RelativeOrAbsolute) }); 
      Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("/Telerik.Windows.Themes.Summer;component/Themes/Telerik.Windows.Controls.Navigation.xaml", UriKind.RelativeOrAbsolute) }); 
      Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("/Telerik.Windows.Themes.Summer;component/Themes/Telerik.Windows.Controls.xaml", UriKind.RelativeOrAbsolute) }); 
      break; 
     } 
     Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("Resources/Brushes.xaml", UriKind.RelativeOrAbsolute) }); 
     Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("Resources/ControlTemplates.xaml", UriKind.RelativeOrAbsolute) }); 
     Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("Resources/DataTemplates.xaml", UriKind.RelativeOrAbsolute) }); 
     Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("Resources/Styles.xaml", UriKind.RelativeOrAbsolute) }); 
    } 

顯然我使用Telerik控制,所以我加載它們的字典,但在方法的底部,您會請注意我也加載了我自己的資源,例如畫筆,樣式等。

總之,使用WPF進行應用程序範圍的主題更改並不容易。

相關問題