設定樣式和範本

更新:2007 年 11 月

Windows Presentation Foundation (WPF) 設計樣式和樣板化是一組功能套件 (樣式、樣板、觸發程序和腳本),可以讓應用程式、文件或使用者介面 (UI) 的設計人員創造出色的視覺效果,並透過標準化使其成品外觀風格保持一致。雖然作者或設計人員可以逐一針對個別應用程式的外觀進行大幅度的自訂設定,但是為了應用程式內部及跨應用程式外觀的維護與共用,仍然需要有一組功能強大的設計樣式及樣板化模型。Windows Presentation Foundation (WPF) 便提供了這樣的模型。

WPF 樣式模型的另一項功能是將展示與邏輯分開來;這表示在開發人員使用 C# 或 Visual Basic 處理程式設計邏輯的同時,設計人員可以只使用 XAML 來處理應用程式的外觀。

本概觀討論設計樣式和範本化簡介的範例應用程式,而該應用程式具有兩個 TextBlock 項目和一個繫結至影像清單的 ListBox 控制項:

已設定樣式的 ListView

本概觀主要著重在應用程式的樣式設計和樣板化,因此並未討論任何資料繫結 (Data Binding) 的概念。如需資料繫結的詳細資訊,請參閱資料繫結概觀

此外,您還必須了解資源的概念,因為資源可以讓您重複使用樣式和樣板。如需資源的詳細資訊,請參閱資源概觀

這個主題包含下列章節。

  • 樣式基本概念
  • 資料範本
  • 控制項樣板
  • 觸發程序
  • 共用資源和佈景主題
  • 相關主題

樣式基本概念

您可以將 Style 視為一種方便使用者將一組屬性值套用到多個項目的方式。例如,以下列 TextBlock 項目及其預設外觀為例:

<TextBlock>My Pictures</TextBlock>
<TextBlock>Check out my new pictures!</TextBlock>

設定樣式範例螢幕擷取畫面

您可以直接在各個 TextBlock 項目上設定諸如 FontSizeFontFamily 等屬性,以變更其預設外觀。不過,如果您想讓 TextBlock 項目共用某些屬性,可以在 XAML 檔案的 Resources 區段中建立 Style,如下所示:

<Window.Resources>


...


<!--A Style that affects all TextBlocks-->
<Style TargetType="TextBlock">
  <Setter Property="HorizontalAlignment" Value="Center" />
  <Setter Property="FontFamily" Value="Comic Sans MS"/>
  <Setter Property="FontSize" Value="14"/>
</Style>


...


</Window.Resources>

當您將樣式的 TargetType 設定為 TextBlock 型別時,樣式便會套用到視窗中的所有 TextBlock 項目。

此時 TextBlock 項目顯示如下:

設定樣式範例螢幕擷取畫面

這個章節包含下列子章節。

  • 擴充樣式
  • TargetType 屬性和 x:Key 屬性的關聯性
  • 樣式和資源
  • 以程式設計方式設定樣式
  • 繫結、動態資源和事件處理常式

擴充樣式

您可能想讓兩個 TextBlock 項目共用某些屬性值,例如 FontFamily 和置中的 HorizontalAlignment,但同時又希望「我的圖片」這幾個字具有其他屬性。如果要這樣做,您可以使用第一個樣式做為基礎來建立新樣式,如下所示:

<Window.Resources>


...


<!--A Style that extends the previous TextBlock Style-->
<!--This is a "named style" with an x:Key of TitleText-->
<Style BasedOn="{StaticResource {x:Type TextBlock}}"
       TargetType="TextBlock"
       x:Key="TitleText">
  <Setter Property="FontSize" Value="26"/>
  <Setter Property="Foreground">
  <Setter.Value>
      <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
        <LinearGradientBrush.GradientStops>
          <GradientStop Offset="0.0" Color="#90DDDD" />
          <GradientStop Offset="1.0" Color="#5BFFFF" />
        </LinearGradientBrush.GradientStops>
      </LinearGradientBrush>
    </Setter.Value>
  </Setter>
</Style>


...


</Window.Resources>

請注意,上述樣式指定了 x:Key。若要套用此樣式,請將 TextBlock 上的 Style 屬性設定為 x:Key 值,如下所示:

<TextBlock Style="{StaticResource TitleText}" Name="textblock1">My Pictures</TextBlock>
<TextBlock>Check out my new pictures!</TextBlock>

如範例中所示,這個 TextBlock 樣式現在的 HorizontalAlignment 值為 CenterFontFamily 值為 Comic Sans MS、FontSize 值為 26,而 Foreground 值則設為 LinearGradientBrush。請注意我們已經覆寫了基底樣式的 FontSize 值。如果 Style 中有一個以上的 Setter 設定相同的屬性,將優先採用最後宣告的 Setter

下圖顯示 TextBlock 項目現在的外觀:

已設定樣式的 TextBlock

這個 TitleText 樣式擴充了 TextBlock 型別已經建立的樣式。您也可以使用 x:Key 值擴充具有 x:Key 的樣式。如需範例,請參閱 BasedOn 屬性所提供的範例。

TargetType 屬性和 x:Key 屬性的關聯性

如第一個範例所示,將 TargetType 屬性設定為 TextBlock 時,如果沒有為樣式指定 x:Key,該樣式便會套用到所有的 TextBlock 項目。在這種情況下,x:Key 會隱含設定為 {x:Type TextBlock}。這表示如果您將 x:Key 值明確設定為 {x:Type TextBlock} 以外的其他值,Style 就不會自動套用到所有的 TextBlock 元件。因此,您必須將樣式 (使用 x:Key 值) 明確套用至 TextBlock 項目。如果樣式位於資源區段而且樣式上並未設定 TargetType 屬性,就必須提供 x:Key。

除了提供 x:Key 的預設值之外,TargetType 屬性也會指定套用 setter 屬性的型別。如果您沒有指定 TargetType,必須使用 Property="ClassName.Property" 的語法,以類別名稱限定 Setter 物件中的屬性。例如,您不能設定 Property="FontSize",而必須將 Property 設定為 "TextBlock.FontSize" 或 "Control.FontSize"。

另外請注意,許多 WPF 控制項都包含其他 WPF 控制項的組合。如果您建立的樣式適用於某種型別的所有控制項,可能會產生無法預期的結果。例如,如果您建立的樣式其目標為 Window 中的 TextBlock 型別,該樣式將會套用到視窗中的所有 TextBlock 控制項,即使 TextBlock 是另一個控制項 (例如 ListBox) 的一部分也一樣。

樣式和資源

您可以將樣式用在衍生自 FrameworkElementFrameworkContentElement 的任何項目上。如前述範例所示,宣告樣式最常用的方式是 XAML 檔案中的 Resources 區段。因為樣式是資源,所以它們會遵守所有資源都適用的相同範圍設定規則;宣告樣式的位置將會影響可以套用樣式的位置。例如,如果您在應用程式定義 XAML 檔案的根項目 (Root Element) 中宣告樣式,您就可以在應用程式的任何位置使用該樣式。如果您建立巡覽應用程式並在應用程式的其中一個 XAML 檔案中宣告樣式,則只能在該 XAML 檔案中使用此樣式。如需資源之範圍設定規則的詳細資訊,請參閱資源概觀

此外,您還可以在本概觀後面的共用資源和佈景主題中找到樣式和資源的詳細資訊。

以程式設計方式設定樣式

若要以程式設計方式將具名樣式指派給項目,請從資源集合中取得樣式,並將它指派給項目的 Style 屬性。請注意,資源集合中的項目屬於型別 Object,因此您必須先將擷取的樣式轉換為 Style,然後才能將它指派給 Style 屬性。例如,若要在名為 textblock1 的 TextBlock 上設定已定義的 TitleText 樣式,請執行下列程式碼:

textblock1.Style = (Style)(this.Resources["TitleText"]);

請注意,一旦套用樣式之後,樣式就會密封而無法變更。如果您想動態變更已經套用的樣式,必須建立新樣式來取代現有的樣式。如需詳細資訊,請參閱 IsSealed 屬性。

您可以建立根據自訂邏輯選擇套用樣式的物件。如需範例,請參閱 StyleSelector 類別所提供的範例。

繫結、動態資源和事件處理常式

請注意,您可以使用 Setter.Value 屬性指定繫結標記延伸DynamicResource 標記延伸。如需詳細資訊,請參閱 Setter.Value 屬性所提供的範例。

目前為止,我們只討論了如何使用 setter 來設定屬性值,但是您也可以在樣式中指定事件處理常式。如需詳細資訊,請參閱 EventSetter

資料範本

這個範例應用程式中有一個繫結到相片清單的 ListBox 控制項。

<ListBox ItemsSource="{Binding Source={StaticResource MyPhotos}}"
         Background="Silver" Width="600" Margin="10" SelectedIndex="0"/>

這個 ListBox 目前的外觀如下:

套用範本之前的 ListBox

大部分的控制項都有某種類型的內容,而這些內容通常是來自您所繫結的資料。在這個範例中,這個資料就是相片清單。在 WPF 中,您可使用 DataTemplate 定義資料的視覺呈現效果。基本上,您放入 DataTemplate 的項目決定了這些資料在呈現之應用程式中的外觀。

在範例應用程式中,每個自訂 Photo 物件都有一個屬於字串型別的 Source 屬性,用於指定影像的檔案路徑。這些相片物件目前都顯示為檔案路徑。

如果要讓相片顯示成影像,您必須建立 DataTemplate 做為資源:

<Window.Resources>


...


<!--DataTemplate to display Photos as images
    instead of text strings of Paths-->
<DataTemplate DataType="{x:Type local:Photo}">
  <Border Margin="3">
    <Image Source="{Binding Source}"/>
  </Border>
</DataTemplate>


...


</Window.Resources>

請注意,DataType 屬性與 StyleTargetType 屬性非常類似。如果 DataTemplate 是在資源區段中,當您將 DataType 屬性指定至某一型別,但是並未指派 x:Key,則每次該型別出現時,都會套用此 DataTemplate。您永遠都可以選擇使用 x:Key 指派 DataTemplate,然後將它設定為 StaticResource,以用於採用 DataTemplate 型別的屬性,例如 ItemTemplate 屬性或 ContentTemplate 屬性。

基本上,上述範例中的 DataTemplate 定義了每當有 Photo 物件時,它都應該顯示成 Border 內的 Image。套用此 DataTemplate 後,應用程式現在看起來就像這樣:

圖片影像

資料樣板化模型提供了其他功能。例如,如果您要顯示的集合資料中包含使用 HeaderedItemsControl 型別 (例如 MenuTreeView) 的其他集合,可以使用 HierarchicalDataTemplate。另一個資料樣板化功能是 DataTemplateSelector,它可以讓您根據自訂邏輯選擇所要使用的 DataTemplate。如需詳細資訊,請參閱資料範本化概觀;其中提供了各種資料樣板化功能的深入討論。

控制項樣板

這個章節包含下列子章節。

  • 不使用 ControlTemplate
  • 什麼是 ControlTemplate
  • 建立 ControlTemplate
  • IsItemsHost 屬性
  • ItemsPresenter 和 ContentPresenter
  • TemplateBinding

現在相片已經顯示成影像,接著請將這些相片從垂直顯示改成水平顯示,也就是將 ListBox 設成水平顯示。

不使用 ControlTemplate

首先,您不需要使用 ControlTemplate 來將 ListBox 設為水平。ListBox 具有 ItemsPanel 屬性,可以讓您設定 ItemsPanelTemplate,也就是用來控制 ListBox 之項目配置的範本。其中一種選擇是直接建立 ListBox 樣式,並設定 ItemsPanel 屬性,如下列範例所示:

<Style TargetType="ListBox">
  <Setter Property="ItemsPanel">
    <Setter.Value>
      <ItemsPanelTemplate>
        <StackPanel Orientation="Horizontal"
                    VerticalAlignment="Center"
                    HorizontalAlignment="Center"/>
      </ItemsPanelTemplate>
    </Setter.Value>
  </Setter>
</Style>

這種方式可以達到效果,並產生水平的 ListBox。這個範例說明了根據實際情況而定,除了取代 ControlTemplate 之外,您可能還有其他選擇。針對這個範例,如果希望水平的 ListBox 具有其他屬性,例如圓角,則必須使用 ListBoxControlTemplate

在提供顯示如何執行這項作業的範例之前,必須先說明 ControlTemplate 的概念。

什麼是 ControlTemplate

大部分的控制項都有外觀和行為。若以按鈕為例:外觀是可以按壓的凸起部分,而行為則是回應點擊動作時所引發的 Click 事件。

有時候控制項可能提供了您所需要的行為,但卻沒有提供需要的外觀。到目前為止,我們已經說明您可以使用樣式 setter 來設定屬性值,以影響控制項的外觀。不過,如果要變更控制項的結構或是在組成控制項的元件上設定屬性值,則必須使用 ControlTemplate

在 WPF 中,控制項的 ControlTemplate 定義了控制項的外觀。您可以為控制項定義新的 ControlTemplate,以變更該控制項的結構和外觀。在許多情況下,這種方式都能夠提供足夠的彈性,因此您不需要自行撰寫自訂控制項。若未自行定義控制項的 ControlTemplate,您會取得符合系統佈景主題的預設樣板,以賦予 Button 控制項預設的外觀。

請牢記,一旦建立控制項的 ControlTemplate 之後,便會取代整個 ControlTemplate。例如,您可以使用下列方式定義 ButtonControlTemplate

請注意,ContentPresenter 項目只會標記 ButtonContent 的位置。我們將在後面的章節中討論不同的項目。

<Style TargetType="Button">
  <!--Set to true to not get any properties from the themes.-->
  <Setter Property="OverridesDefaultStyle" Value="True"/>
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="Button">
        <Grid>
          <Ellipse Fill="{TemplateBinding Background}"/>
          <ContentPresenter HorizontalAlignment="Center"
                            VerticalAlignment="Center"/>
        </Grid>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

套用此程式碼後,Button 便會顯示成 Ellipse

Button ControlTemplate 範例

請注意,Button 在取得焦點或按下時的外觀全都是您要取代之按鈕的預設外觀。因此,根據您的需求,您可能需要在定義中加入在按下時按鈕應該呈現的外觀。如需完整的範例,請參閱 Button ControlTemplate 範例

如果要建立 ControlTemplate,最佳入門方式是使用 ControlTemplate 範例。如果您真的需要檢視控制項的組成內容,可以查看位於主題中的主題檔案,也可以使用 XAMLPad (與 Windows Software Development Kit (SDK) 一起安裝的應用程式) 的 [Show Visual Tree] 功能。

建立 ControlTemplate

現在我們將沿續前面的範例,並建立 ControlTemplate 以定義具有圓角的水平 ListBox。若要取代控制項的 ControlTemplate,請將 Template 屬性設定為新的 ControlTemplate

<Style TargetType="ListBox">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="ListBox">
        <Border CornerRadius="5" Background="{TemplateBinding ListBox.Background}">
          <ScrollViewer HorizontalScrollBarVisibility="Auto">
            <StackPanel Orientation="Horizontal"
                       VerticalAlignment="Center"
                       HorizontalAlignment="Center"
                       IsItemsHost="True"/>
          </ScrollViewer>
        </Border>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

以這種方式設定 Template 屬性,實際上與使用 Style 設定其他控制項屬性並無不同:您會使用 Style 做為設定 Template 屬性的輔助工具。這表示設定 ControlTemplate 的另一種方式是直接在控制項上設定 Template 屬性。如果採用這種方式,您會在 Resources 區段中建立 ControlTemplate,為其提供 x:Key,然後將它當做靜態資源使用。如需範例,請參閱 Template 屬性。

如前述範例所示,ControlTemplate 類別擁有 TargetType 屬性,而這個屬性與 Style 類別的 TargetType 屬性類似。不過請注意,與 StyleDataTemplate 不同,ControlTemplate 物件並沒有隱含索引鍵的概念。換句話說,如果您有獨立的 ControlTemplate,而其 TargetType 屬性設定為某個型別,ControlTemplate 並不會自動套用至該型別。另外請注意,如果樣板定義包含 ContentPresenterControlTemplate 中就必須有 TargetType 屬性。

請嘗試使用 ControlTemplate 進行實驗。例如,請將 StackPanel 取代成 WrapPanel,將 ScrollViewerHorizontalScrollBarVisibility 屬性設定為 Disabled,然後再將 ListBox 的 Width 設定成 300 (當第一列的空間用盡時,WrapPanel 只會將項目放到下一列。如果沒有將 ScrollViewerHorizontalScrollBarVisibility 屬性設定為 Disabled,第一列的空間不會用盡,因為您可以捲動至結尾處。因此,WrapPanel 不會將項目換行)。

IsItemsHost 屬性

這個範例中必須存在的一個重要屬性是 IsItemsHost 屬性。IsItemsHost 屬性可用來指定樣板中產生之項目所在位置的 ItemsControl (諸如 ListBox 等處理項目清單的控制項)。在 StackPanel 上將屬性設定為 true 表示加入至 ListBox 的任何項目都會放入 StackPanel 中。請注意,這個屬性只適用於 Panel 型別。

ItemsPresenter 和 ContentPresenter

不過,請注意當您在 ControlTemplate 中指定面板,並以這種方式將它標記為 IsItemsHost 時,除非使用 ControlTemplate,否則控制項的使用者將無法取代 ItemsPanel。因此,只有在您確定不想以未使用範本的方式取代面板時,才能採用這種方式。此外,您也可以使用 ItemsPresenter 項目標記項目的位置,然後再透過設定 ItemsPanel 屬性來指定 ItemsPanelTemplateItemsPanelTemplate 頁面包含說明如何執行這項程序的範例。如需使用 ItemsPresenter 的其他範例,請參閱 TreeView ControlTemplate 範例

如果您要建立 ContentControl (例如 Button) 的樣板,對應的項目是 ContentPresenter。同樣地,請將這個項目放在 ContentControl 型別的 ControlTemplate 中,以指定顯示內容的位置;相關範例請參見什麼是 ControlTemplate?區段。如需其他範例,請參閱 Label ControlTemplate 範例ListBoxItem ControlTemplate 範例

TemplateBinding

在前述範例中,另一個必須注意的重點是設定為 {TemplateBinding ListBox.Background} 的 Background 值。這項設定只表示 BorderBackground 應該與 ListBox 上設定的 Background 值同步 (Synchronize)。TemplateBinding 與 Binding 類似。實際上,TemplateBinding 的效率高於 Binding 但功能較少;使用 TemplateBinding 等於使用 Binding 並將 Source 屬性設定為 RelativeSourceTemplatedParent.

若想賦予控制項使用者對特定屬性值的控制權,請在 ControlTemplate 中使用 TemplateBinding。TemplateBinding 是由 TemplateBindingExtension 類別所表示的標記延伸。

您可能已經注意到 DataTemplateControlTemplate 兩者十分類似,因為它們的內容都會變成物件的視覺顯示。定義 ListBoxControlTemplate 後,應用程式現在看起來就像這樣:

設定樣式範例螢幕擷取畫面

觸發程序

StyleControlTemplateDataTemplate 全部都有可以包含一組觸發程序 (Trigger) 的 Triggers 屬性。觸發程序可設定屬性,或是在變更屬性值或引發事件時啟動動作 (例如動畫)。

這個章節包含下列子章節。

  • 屬性觸發程序
  • EventTrigger 和 Storyboard
  • MultiTrigger、DataTrigger 和 MultiDataTrigger

屬性觸發程序

為了示範如何使用觸發程序來設定屬性,我們會將每個 ListBoxItem 設定成半透明,但選取時除外。

下列樣式將 ListBoxItemOpacity 值設定為 0.5。不過,當 IsSelected 屬性為 true 時,Opacity 便會設定為 1.0:

<Style TargetType="ListBoxItem">
  <Setter Property="Opacity" Value="0.5" />
  <Setter Property="MaxHeight" Value="75" />
  <Style.Triggers>
    <Trigger Property="IsSelected" Value="True">
        <Setter Property="Opacity" Value="1.0" />
    </Trigger>


...


  </Style.Triggers>
</Style>

這個範例使用 Trigger 設定屬性值,但請注意 Trigger 類別也有 EnterActionsExitActions 屬性,可以啟用觸發程序來執行動作。

請注意,我們也將 ListBoxItemMaxHeight 屬性設定為 75。在下列螢幕擷取畫面中,第三個項目是選取的項目:

已設定樣式的 ListView

EventTrigger 和 Storyboard

我們剛才已說明 Trigger 會設定屬性值或根據屬性的值來啟動動作。另一種觸發程序類型是 EventTrigger,它會根據發生的事件啟動一組動作。例如,下列 EventTrigger 物件指定當滑鼠指標進入 ListBoxItem 時,MaxHeight 屬性會在 0.2 的期間內,產生值為 90 的動畫效果。當滑鼠從項目移開時,此屬性便會在 1 秒的期間內恢復成原始值。請注意,您不需要指定 MouseLeave 動畫的 To 值,因為動畫可以追蹤原始值。

<EventTrigger RoutedEvent="Mouse.MouseEnter">
  <EventTrigger.Actions>
    <BeginStoryboard>
      <Storyboard>
        <DoubleAnimation
          Duration="0:0:0.2"
          Storyboard.TargetProperty="MaxHeight"
          To="90"  />
      </Storyboard>
    </BeginStoryboard>
  </EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
  <EventTrigger.Actions>
    <BeginStoryboard>
      <Storyboard>
        <DoubleAnimation
          Duration="0:0:1"
          Storyboard.TargetProperty="MaxHeight"  />
      </Storyboard>
    </BeginStoryboard>
  </EventTrigger.Actions>
</EventTrigger>

如需詳細資訊,請參閱腳本概觀

在下列螢幕擷取畫面中,滑鼠指向第三個項目:

設定樣式範例螢幕擷取畫面

MultiTrigger、DataTrigger 和 MultiDataTrigger

除了 TriggerEventTrigger 之外,還有其他類型的觸發程序。MultiTrigger 可讓您根據多項條件來設定屬性值。當條件的屬性與資料繫結時,請使用 DataTriggerMultiDataTrigger

如需本概觀中討論的完整範例,請參閱設計樣式和範本化簡介的範例

共用資源和佈景主題

一般的 Windows Presentation Foundation (WPF) 應用程式可能具有多項使用者介面 (UI) 資源可套用到整個應用程式。這一整組資源可以視為應用程式的佈景主題。Windows Presentation Foundation (WPF) 提供使用封裝為 ResourceDictionary 類別之資源字典,將使用者介面 (UI) 資源封裝為佈景主題的支援。

Windows Presentation Foundation (WPF) 佈景主題是使用 Windows Presentation Foundation (WPF) 為了自訂任何項目之視覺效果而公開的設計樣式和樣板化機制來定義。

Windows Presentation Foundation (WPF) 佈景主題資源儲存在內嵌的資源字典中。這些資源字典必須內嵌在簽署的組件內,而且可以內嵌在與程式碼本身相同的組件中,或是並存組件中。以內含 Windows Presentation Foundation (WPF) 控制項的 PresentationFramework.dll 組件為例,佈景主題資源是位於一系列的並存組件中。

佈景主題會變成搜尋項目樣式時最後查看的位置。搜尋作業通常是從項目樹狀結構向上查核以搜尋適當的資源開始,接著查看應用程式資源集合,最後再查詢系統。這種方式使得應用程式作者在達到佈景主題之前,有機會在樹狀結構或應用程式層級重新定義任何項目的樣式。

您可以將資源字典定義成個別檔案,使您可以在多個應用程式之間重複使用佈景主題。您也可以定義多個資源字典,使其提供相同的資源類型但具有不同的值,藉以建立可切換的佈景主題。建議您透過設定應用程式的面板,在應用程式層級重新定義這些樣式或其他資源。

若要跨應用程式共用一組資源 (包括樣式和樣板),您可以建立 XAML 檔案並定義 ResourceDictionary。例如,請參見下列螢幕擷取畫面;其中顯示使用 ControlTemplates 設定樣式範例的一部分:

控制項範本範例

若查看此範例中的 XAML 檔案,您會發現這些檔案都有下列內容:

<ResourceDictionary.MergedDictionaries>
  <ResourceDictionary Source="Shared.xaml" />
</ResourceDictionary.MergedDictionaries>

這是 shared.xaml 的共用,其中定義的 ResourceDictionary 包含一組樣式和筆刷資源,可以讓範例中的控制項擁有一致的外觀。

如需詳細資訊,請參閱合併的資源字典

如果您要建立自訂控制項的佈景主題,請參閱控制項撰寫概觀中的<外部控制項程式庫>一節。

請參閱

工作

HOW TO:尋找 ControlTemplate 產生的項目

HOW TO:尋找 DataTemplate 產生的項目

相片存放區示範

概念

Windows Presentation Foundation 中的 Pack URI

其他資源

主題