2011年5月27日 星期五

在WPF 中對所有的 UserControl 作樣式設定

需求

在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 的樣式套用了指定的樣式,看起來是可以的樣子哦!(當然沒這麼簡單,不然就不用寫這一篇了)

image

執行起來畫面就是沒有套用到。

image

程式的部份,請看附件的 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 並沒有值。

image

程式的部份,請看附件的 WpfApplicatioin3 這個專案

最後版本

不知道這是不是 bug。結果還是動用了 code behind 來解決事情。

public class MyUserControl : UserControl
{
public MyUserControl()
{
  this.Style = this.FindResource("baseStyle") as Style;
}
}

使用 Snoop 來看,終於有套用到 style 了

SNAGHTML27d2b2c

程式的部份,請看附件的 WpfApplicatioin4 這個專案

結論

這是 WPF 4 的 bug 嗎?不知道。只知道浪費了2小時的時間。

沒有留言:

Share with Facebook