WPF基礎之樣式設置和模板化(二)

實質上,上面示例的 DataTemplate 確定只要存在 Photo 對象,該對象就應作爲 Image 顯示在 Border 中。通過此 DataTemplate,應用程序現在的外觀如下:


數據模板化模型還提供其他功能。例如,如果要使用 HeaderedItemsControl 類型(如 Menu 或 TreeView)顯示包含其他集合的集合數據,則可以使用 HierarchicalDataTemplate。另一個數據模板化功能是 DataTemplateSelector,利用這一功能可以根據自定義邏輯選擇要使用的 DataTemplate。有關更多信息,請參見數據模板概述,該概述對不同的數據模板化功能進行了更加深入的討論。

控件模板

請注意,我們的照片顯示爲圖片,我們要水平顯示這些照片,而不是垂直顯示;我們希望 ListBox 是水平的。

不使用 ControlTemplate
首先,要使 ListBox 水平,不一定要使用 ControlTemplate,明確這一點很重要。ListBox 具有 ItemsPanel 屬性,利用該屬性可以設置 ItemsPanelTemplate,即控制 ListBox 的項的佈局的模板。一種方法是隻創建 ListBox 樣式,然後設置 ItemsPanel 屬性,如下例所示:

 

例表明,除了替換 ControlTemplate 之外,可能還有其他方法,這取決於具體的情況。在本示例中,如果希望獲得具有其他屬性(如圓角)的水平 ListBox,則需要使用 ListBox 的 ControlTemplate。

在提供示例來演示具體操作之前,首先需要說明 ControlTemplate 的概念。

什麼是 ControlTemplate?
大多數控件都具有外觀和行爲。以按鈕爲例:外觀是可以按下的凸起區域,行爲是在響應單擊時所引發的 Click 事件。

有時,控件可以提供所需行爲,但不具有所需外觀。到目前爲止,我們已經演示了可以使用樣式 setter 來設置屬性值,從而影響控件的外觀。但是,若要更改控件的結構,或對組成控件的組件設置屬性值,就需要使用 ControlTemplate。

在 WPF 中,控件的 ControlTemplate 定義控件的外觀。通過爲控件定義新的 ControlTemplate 可以更改控件的結構和外觀。很多情況下,這種方法都足夠靈活,您不需要自己編寫自定義控件。如果沒有爲控件定義自己的 ControlTemplate,則可以獲取與系統主題匹配的默認模板,該模板向 Button 控件提供默認外觀。

請注意:一旦爲控件創建 ControlTemplate,就會替換整個 ControlTemplate。例如,可以通過以下方式定義 Button ControlTemplate。

請注意,ContentPresenter 元素只標記 Button 的 Content 應出現在何處。後面有一節專門展開詳細討論。

 

應用此模板之後,Button 顯示爲 Ellipse:


請記住,當 Button 具有焦點或按下時,其外觀都是將替換的按鈕的默認外觀的組成部分。因此,您可能希望定義按鈕按下時的外觀,這取決於您的具體需要。

如果要創建 ControlTemplate,使用 ControlTemplate 示例 是最好的入門方法。如果確實需要查看控件的組成部分,可以查看位於主題的主題文件,也可以使用 XAMLPad(隨 Windows 軟件開發工具包 (SDK) 安裝的應用程序)的 Show Visual Tree 功能。

創建 ControlTemplate
現在,繼續演示示例,我們創建一個 ControlTemplate,它定義一個水平的圓角 ListBox。若要替換控件的 ControlTemplate,請將 Template 屬性設置爲新的 ControlTemplate。

 

以這種方式設置 Template 屬性,實際上與使用 Style 設置其他控件屬性沒有區別:您將 Style 用作一個工具來幫助設置 Template 屬性。也就是說,設置 ControlTemplate 的另一種方法是直接設置控件的 Template 屬性。如果以這種方式設置,則會在 Resources 節中創建一個 ControlTemplate,併爲它提供 x:Key,然後將它作爲靜態資源使用。

如上例所示,ControlTemplate 類具有 TargetType 屬性,該屬性類似於 Style 類的 TargetType 屬性。但要注意,與 Style 和 DataTemplate 不同,ControlTemplate 對象沒有隱式鍵的概念。換言之,如果有一個獨立 ControlTemplate,其 TargetType 屬性設置爲某個類型,則 ControlTemplate 不會自動應用於該類型。另請注意,如果模板定義包含 ContentPresenter,則 ControlTemplate 需要 TargetType 屬性。

嘗試使用 ControlTemplate。例如,用 WrapPanel 替換 StackPanel,將 ScrollViewer 的 HorizontalScrollBarVisibility 屬性設置爲 Disabled,然後將 ListBox 的寬度設置爲 300。(只有第一行空間不足時,WrapPanel 纔會將項放置到下一行。如果沒有將 ScrollViewer 的 HorizontalScrollBarVisibility 屬性設置爲 Disabled,由於可以滾動到末尾,則第一行不會空間不足。因此,WrapPanel 不會對項進行換行。)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章