需求
在WPF 中如何一次對所有的 UserControl 作樣式設定呢?
第一版
在 WPF 中,要對同一個 Control 作預設的樣式設定很簡單。只需要在 App.xaml 中設定即可。
App.xaml
<Application x:Class="WpfApplication1.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml"> <Application.Resources> <Style TargetType="UserControl"> <Setter Property="Background" Value="Gray" /> </Style> </Application.Resources> </Application>
在 Visual Studio 中,可以在 designer 看到 usercontrol 的樣式套用了指定的樣式,看起來是可以的樣子哦!(當然沒這麼簡單,不然就不用寫這一篇了)
執行起來畫面就是沒有套用到。
程式的部份,請看附件的 WpfApplicatioin1 這個專案。
第二版
不信邪的我,稍稍改動了一下,讓樣式直接指定 UserControl1。這樣就可以套用樣式了。
<Application x:Class="WpfApplication2.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication2" StartupUri="MainWindow.xaml"> <Application.Resources> <Style TargetType="{x:Type local:UserControl1}"> <Setter Property="Background" Value="Gray" /> </Style> </Application.Resources> </Application>
這樣子只能套用到指定的 UserControl1,而非所有的樣式。原因是:樣式雖然可以像「繼承」樣子套用到指定的 Type,但不是繼承出來的 Type 都可以套用父類別的樣式。
程式的部份,請看附件的 WpfApplicatioin2 這個專案
第三版
這一版,自已加上了一個自訂的 MyUserControl 並繼承自 UserControl。之後,所有的 UserControl 都改繼承自訂的 MyUserControl。
在 App.xaml 中,樣式使用 BaseOn 這個關鍵。
<Application x:Class="WpfApplication3.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication3" StartupUri="MainWindow.xaml"> <Application.Resources> <Style TargetType="UserControl" x:Key="baseStyle"> <Setter Property="Background" Value="Gray" /> </Style> <Style TargetType="{x:Type local:MyUserControl}" BasedOn="{StaticResource baseStyle}" /> </Application.Resources> </Application>
滿心歡喜地以為這樣萬事 OK 了,結果還是失敗。使用 Snoop 來查一下,Style 並沒有值。
程式的部份,請看附件的 WpfApplicatioin3 這個專案
最後版本
不知道這是不是 bug。結果還是動用了 code behind 來解決事情。
public class MyUserControl : UserControl { public MyUserControl() { this.Style = this.FindResource("baseStyle") as Style; } }
使用 Snoop 來看,終於有套用到 style 了
程式的部份,請看附件的 WpfApplicatioin4 這個專案
結論
這是 WPF 4 的 bug 嗎?不知道。只知道浪費了2小時的時間。