淺談WPF之各種Template

前幾天寫了一篇文章【淺談WPF之控件模板和數據模板】,有粉絲反饋說這兩種模板容易弄混,不知道什么時候該用控件模塊,什么時候該用數據模板,以及template和itemtemplate之間的關系等,今天專門寫一篇文章,簡述WPF中各種模板及其相互關系。僅供學習分享使用,如有不足之處,還請指正。

概述

在WPF中,一共有三種模板,分別如下:

  • 控件模板ControlTemplate,用來指定控件的呈現樣式。
  • 數據模板DataTemplate,用來指定子項數據的呈現樣式。
  • 子控件模板ItemsPanelTemplate,用來指定子項控件的布局樣式。

模板與控件之間的關系

關于各個模板與控件之間的關系,如下圖所示:

通過上圖可以看出:

  1. Control擁有Template屬性,是ControlTemplate類型,所有Control派生的子控件,都具有Template屬性,都可以通過控件模板設置控件的樣式。
  2. ContentControl擁有ContentTemplate屬性,是DataTemplate類型,所有ContentControl派生的控件,都具有ContentTemplate屬性,如Button,ListBoxItem,DataGridCell等。
  3. ItemsControl擁有ItemsTemplate屬性,是DataTemplate類型,所有ItemsControl派生的控件,都具有ItemsTemplate屬性,如ListBox,ComboBox,DataGrid,ListView等。
  4. ItemsControl擁有ItemsPanel屬性,是ItemsPanelTemplate類型,所有ItemsControl派生的控件,都具有ItemsPanel屬性,如ListBox,ComboBox,DataGrid,ListView等。
  5. Template,ContentTemplate,ItemsTemplate,ItemsPanel只是屬性名稱,而DataTemlate,ControlTemplate,ItemsPanelTemplate才是模板類型。

ControlTemplate控件模板詳解

利用ControlTemplate可以徹底的顛覆控件的默認外觀。<ControlTemplate>里面的內容就是視覺樹VisualTree。
兩個重要屬性:

a)ContentPresenter

重定義控件模板,默認模板將會被覆蓋,此時需要利用ContentPresenter,把原有模板的屬性原封不動的投放到自定義模板中。

b)Triggers

觸發器列表,里面包含一些觸發器Trigger,我們可以定制這個觸發器列表來使控件對外界的刺激發生反應,比如鼠標經過時文本變成粗體等。

控件模板示例

<Window x:Class="WpfApplication1.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:sys="clr-namespace:System;assembly=mscorlib"Title="MainWindow" Height="350" Width="525"><Window.Resources><ControlTemplate x:Key="rect" TargetType="{x:Type CheckBox}"><ControlTemplate.Resources><SolidColorBrush x:Key="redBrush" Color="Red"/></ControlTemplate.Resources><StackPanel><Rectangle Name="breakRectangle" Stroke="Red" StrokeThickness="2" Width="20" Height="20"><Rectangle.Fill><SolidColorBrush Color="White"/></Rectangle.Fill></Rectangle><ContentPresenter/></StackPanel><ControlTemplate.Triggers><Trigger Property="IsChecked" Value="True"><Setter TargetName="breakRectangle" Property="Fill" Value="{StaticResource ResourceKey=redBrush}"></Setter></Trigger></ControlTemplate.Triggers></ControlTemplate></Window.Resources><Canvas><CheckBox Template="{StaticResource ResourceKey=rect}"  Content="我是CheckBox"/></Canvas>
</Window>

?

注意:<ContentPresenter Margin="{TemplateBinding Padding}" /> 實現了將模板中的Margin綁定到原控件中的Padding上去。

將控件模板寫到樣式里面,如下所示:

<Style x:Key="cbx" TargetType="{x:Type CheckBox}"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type CheckBox}"><ControlTemplate.Resources><SolidColorBrush x:Key="redBrush" Color="Red"/></ControlTemplate.Resources><StackPanel><Rectangle Name="breakRectangle" Stroke="Red" StrokeThickness="2" Width="20" Height="20"><Rectangle.Fill><SolidColorBrush Color="White"/></Rectangle.Fill></Rectangle><ContentPresenter/></StackPanel><ControlTemplate.Triggers><Trigger Property="IsChecked" Value="True"><Setter TargetName="breakRectangle" Property="Fill" Value="{StaticResource ResourceKey=redBrush}"></Setter></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter>
</Style>

?

通過綁定樣式資源,如下所示:

<CheckBox Style="{StaticResource ResourceKey=cbx}" Content="我是CheckBox"/>

?

c)ItemsPresenter

繼承自ItemsControl的控件,有一個ItemsPanel屬性作為集合元素承載容器。子元素ItemsPresenter負責呈現控件的任務。

只要把ItemsPresenter放在內部模板中,那么ItemsPresenter則會去檢測父元素是否為集合控件,然后將ItemsPanel添加到其內部視覺樹當中。

<Style x:Key="{x:Type ItemsControl}" TargetType="{x:Type ItemsControl}"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type ItemsControl}"><Border Background="{TemplateBinding Background}"BorderBrush="{TemplateBinding BorderBrush}"BorderThickness="{TemplateBinding BorderThickness}"Padding="{TemplateBinding Padding}"SnapsToDevicePixels="true"><ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/></Border></ControlTemplate></Setter.Value></Setter>
</Style>

?

比較常見的繼承自ItemsControl的控件,比如ComboBox,ContextMenu,ListBox,DataGrid,ListView等。

DataTemplate數據模板詳解

數據模板定義了數據的顯示方式,也就是數據對象的可視結構。主要是可以自定義控件的同時進行數據綁定。

<Window x:Class="WpfApplication1.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:sys="clr-namespace:System;assembly=mscorlib"xmlns:src="clr-namespace:WpfApplication1"Title="MainWindow" Height="350" Width="525"><Window.Resources><ObjectDataProvider x:Key="personList" ObjectType="{x:Type src:PersonList}"/><DataTemplate x:Key="rect"><Border Name="border" BorderBrush="Aqua" BorderThickness="1" Padding="5" Margin="5"><StackPanel><StackPanel Orientation="Horizontal"><TextBlock Text="{Binding Name}" Margin="5,0,0,0"/><TextBlock Text="{Binding Age}" Margin="5,0,0,0"/></StackPanel><StackPanel Orientation="Horizontal"><TextBlock Text="{Binding Address}" Margin="5,0,0,0"/></StackPanel></StackPanel></Border></DataTemplate></Window.Resources><Grid><ListBox ItemsSource="{Binding Source={StaticResource ResourceKey=personList}}"ItemTemplate="{StaticResource ResourceKey=rect}"></ListBox></Grid>
</Window>

?

注意:這里在調用時應該綁定的是 ItemTemplate 屬性。?

ItemsPanelTemplate詳解

首先我們要知道常見的條目控件有:ListBox,Menu,StatusBar等。

比如拿ListBox來說,ItemBox的ItemPanel其實是一個VisualizingStackPanel,就是說ListBox的每一項的排列方式是遵循StackPanel的

原則,也就是從上到下的排列方式。如果要實現從左到右排列:

<Window x:Class="WpfApplication1.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:sys="clr-namespace:System;assembly=mscorlib"xmlns:src="clr-namespace:WpfApplication1"Title="MainWindow" Height="350" Width="525"><Window.Resources><ObjectDataProvider x:Key="personList" ObjectType="{x:Type src:PersonList}"/><DataTemplate x:Key="rect"><Border Name="border" BorderBrush="Aqua" BorderThickness="1" Padding="5" Margin="5"><StackPanel><StackPanel Orientation="Horizontal"><TextBlock Text="{Binding Name}" Margin="5,0,0,0"/><TextBlock Text="{Binding Age}" Margin="5,0,0,0"/></StackPanel><StackPanel Orientation="Horizontal"><TextBlock Text="{Binding Address}" Margin="5,0,0,0"/></StackPanel></StackPanel></Border></DataTemplate><ItemsPanelTemplate x:Key="items"><StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center"/></ItemsPanelTemplate></Window.Resources><Grid><ListBox ItemsSource="{Binding Source={StaticResource ResourceKey=personList}}"ItemTemplate="{StaticResource ResourceKey=rect}" ItemsPanel="{StaticResource ResourceKey=items}"></ListBox></Grid>
</Window>

也就是說,ItemsPanelTemplate可以用來定義集合控件的容器外觀。

總結

1、Template


控件模板,是指整個控件的展示和布局。
如ComboBox,可分為文本區域,下拉按鈕區域,Items的Popup區域。
Template就是管理這些位置的布局。

2、ItemsPresenter


可以簡單理解為占位符,在樣式中使用,標記著這個區域用來展示該控件的Items。
如:ComboBox的下拉列表的可選項。
但是,只負責顯示,而不能管理如何顯示,如果我們要內容橫向排列,就要用到ItemsPanel。

3、ItemsPanel


管理Items的排列方式,如,ComboBox默認是豎直排列的,我們要橫著排列,只需要定義ItemsPanel為WrapPanel,就可以了。
這時候Items的排列方式已經完成,如果還要讓ComboBox的每個項都重寫,比如,背景、圖標等,就要用到ItemContainerStyle。

4、ItemContainerStyle


就是每個項的樣式,自己重寫,就可以定制出每個項的樣式了。

以上就是淺談WPF之各種模板的全部內容。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/161975.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/161975.shtml
英文地址,請注明出處:http://en.pswp.cn/news/161975.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

26 - 原型模式與享元模式:提升系統性能的利器

原型模式和享元模式&#xff0c;前者是在創建多個實例時&#xff0c;對創建過程的性能進行調優&#xff1b;后者是用減少創建實例的方式&#xff0c;來調優系統性能。這么看&#xff0c;你會不會覺得兩個模式有點相互矛盾呢&#xff1f; 其實不然&#xff0c;它們的使用是分場…

TC397 EB MCAL開發從0開始系列 之 [15.1] Fee配置 - 雙扇區demo

一、Fee配置1、配置目標2、目標依賴2.1 硬件使用2.2 軟件使用2.3 新增模塊3、EB配置3.1 配置講解3.2 模塊配置3.2.1 MCU配置3.2.2 PORT配置3.2.3 Fls_17_Dmu配置3.2.4 Fee配置3.2.5 Irq配置3.2.6 ResourceM配置4、ADS代碼編寫及調試4.1 工程編譯4.2 測試結果4.3 測例源碼->

2023年學習Go語言是否值得?探索Go語言的魅力

關注公眾號【愛發白日夢的后端】分享技術干貨、讀書筆記、開源項目、實戰經驗、高效開發工具等&#xff0c;您的關注將是我的更新動力&#xff01; 作為一門流行且不斷增長的編程語言&#xff0c;Go語言在2023年是否值得學習呢&#xff1f;讓我們來看看學習Go語言的好處以及為何…

Java使用Maven打包jar包的全部方式

1. spring-boot-maven-plugin插件&#xff08;在springboot項目中使用&#xff09; <plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><executions><execution><goals>…

1410.HTML 實體解析器

??題目來源&#xff1a; leetcode題目&#xff0c;網址&#xff1a;1410. HTML 實體解析器 - 力扣&#xff08;LeetCode&#xff09; 解題思路&#xff1a; 使用map存放特殊字符串及其應被替換為的字符串。然后遍歷字符串替換 map 中的字符串即可。 解題代碼&#xff1a; …

ubuntu 手動清理內存cache

/proc是一個虛擬文件系統&#xff0c;我們可以通過對它的讀寫操作來做為與kernel實體間進行通信的一種手段。也就是說可以通過修改/proc中的文件&#xff0c;來對當前kernel的行為做出調整。 那么我們可以通過調整/proc/sys/vm/drop_caches來釋放內存。操作如下&#xff1a; …

富士康轉移產線和中國手機海外設廠,中國手機出口減少超5億部

富士康和蘋果轉移生產線對中國手機制造造成了巨大的影響&#xff0c;除此之外&#xff0c;中國手機企業紛紛在海外設廠也在減少中國手機的出口&#xff0c;2022年中國的手機出口較高峰期減少了5.2億部。 手機是中國的大宗出口商品&#xff0c;不過公開的數據顯示2022年中國的手…

每日OJ題_算法_雙指針_力扣202. 快樂數

力扣202. 快樂數 202. 快樂數 - 力扣&#xff08;LeetCode&#xff09; 難度 簡單 編寫一個算法來判斷一個數 n 是不是快樂數。 「快樂數」 定義為&#xff1a; 對于一個正整數&#xff0c;每一次將該數替換為它每個位置上的數字的平方和。然后重復這個過程直到這個數變為…

RT-Thread 線程間同步【信號量、互斥量、事件集】

線程間同步 一、信號量1. 創建信號量2. 獲取信號量3. 釋放信號量4. 刪除信號量5. 代碼示例 二、互斥量1. 創建互斥量2. 獲取互斥量3. 釋放互斥量4. 刪除互斥量5. 代碼示例 三、事件集1. 創建事件集2. 發送事件3. 接收事件4. 刪除事件集5. 代碼示例 簡單來說&#xff0c;同步就是…

PDF轉成圖片

使用開源庫Apache PDFBox將PDF轉換為圖片 依賴 <dependency><groupId>org.apache.pdfbox</groupId><artifactId>fontbox</artifactId><version>2.0.4</version> </dependency> <dependency><groupId>org.apache…

DockerHub 無法訪問 - 解決辦法

背景 DockerHub 鏡像倉庫地址 https://hub.docker.com/ 突然就無法訪問了,且截至今日(2023/11)還無法訪問。 這對我們來說,還是有一些影響的: ● 雖然 DockerHub 頁面無法訪問,但是還是可以下載鏡像的,只是比較慢而已 ● 沒法通過界面查詢相關鏡像,或者維護相關鏡像了…

JAVA 使用stream流將List中的對象某一屬性創建新的List

JAVA 使用stream流將List中的對象某一屬性創建新的List 1.stream流介紹 Java Stream是Java 8引入的一種新機制&#xff0c;它可以讓我們以聲明式方式操作集合數據&#xff0c;提供了更加簡潔、優雅的集合處理方式。Stream是一個來自數據源的元素隊列&#xff0c;并支持聚合操…

【Rxjava詳解】(二) 操作符的妙用

文章目錄 接口變化操作符mapflatmapdebouncethrottleFirst()takeconcat RxJava 是一個基于 觀察者模式的異步編程庫&#xff0c;它提供了豐富的操作符來處理和轉換數據流。 操作符是 RxJava 的核心組成部分&#xff0c;它們提供了一種靈活、可組合的方式來處理數據流&#xf…

C++二分算法:得到子序列的最少操作次數

本文涉及的基礎知識點 二分查找算法合集 題目 給你一個數組 target &#xff0c;包含若干 互不相同 的整數&#xff0c;以及另一個整數數組 arr &#xff0c;arr 可能 包含重復元素。 每一次操作中&#xff0c;你可以在 arr 的任意位置插入任一整數。比方說&#xff0c;如果…

【如何學習Python自動化測試】—— 多層窗口定位

6 、 多層窗口定位 多層窗口指的是在操作系統圖形界面中&#xff0c;一個窗口被另一個窗口覆蓋的情況。在多層窗口中&#xff0c;如何定位需要操作的窗口&#xff1f; 一種常見的方法是使用操作系統提供的AltTab快捷鍵&#xff0c;可以在打開的所有窗口中快速切換焦點。如果需要…

第十三章 控制值的轉換 - 處理UTC時區指示符

文章目錄 第十三章 控制值的轉換 - 處理UTC時區指示符 第十三章 控制值的轉換 - 處理UTC時區指示符 對于支持XML的類&#xff0c;可以指定在從XML文檔導入時是否使用UTC時區指示符。同樣&#xff0c;可以指定是否在導出時包含UTC時區指示符。 為此&#xff0c;指定XMLTIMEZON…

GEE生物量碳儲量——利用sens和MK檢驗方法計算1987-2022年森林地上生物量AGB和碳儲量的時空變化特征

簡介: 本文是將之前已經處理好的森林生物量和碳儲量數據保存到GEE Assets中,然后分別將單張影像導入到代碼編輯器中,構建一個時間序列集合,并且這里需要用到的是我們給影像添加指定的時間屬性,這樣方便進行下一步的時序分析和空間預測。 首先,需要收集1987年至2022年期…

C語言實現Linux下TCP Server測試工具

Linux TCP Server測試工具代碼 實現了接受數據并輸出文本和十六制字符串 #include <stdio.h> #include<string.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <signal.h> #include <arpa/inet.h> #incl…

STM32內存介紹

ROM是一種只讀存儲器&#xff0c;經歷了從NOR Flash到NAND Flash再到現在的eMMC的發展。為了便于使用和大批量生產&#xff0c;ROM進一步分為了4種類型&#xff1a;PROM、EPROM、EEPROM和Flash。PROM只能被編程一次&#xff0c;EPROM可擦寫可編程且可達1000次&#xff0c;EEPRO…