WPF Step By Step 自定義模板

本文大綱

一、控件模板及數據模板數據庫

二、ListBox深度定製模板。數據結構

三、TreeView高級模板使用實例。性能

控件模板及數據模板

 

控件模板

什麼是控件模板,指定能夠在控件的多個實例之間共享 Control 的可視結構和性能方面的方面。控件模板其實就是咱們在可視方面的自定義模板,ControlTemplate 容許您指定控件的可視結構。 重寫 ControlTemplate 從新生成該控件的可視結構。動畫

模板化控件是 WPF 提供的許多功能之同樣式設置和模板化模型。 該樣式和模板化模型提供了許多狀況下您不須要編寫擁有控件這樣的大的靈活性。this

控件模板包含二方面的內容:VisualTree和Tigger。本篇介紹的內容,徹底都是基於這二塊的內容進行討論和說明。spa

什麼是ViewTree

VisualTree就是對應WPF控件的可視元素的定義,下面來舉例說明:設計

image

上面,咱們經過了lable重寫了button按鈕的控件模板,咱們還能夠採用更復雜的控件來重寫它:3d

image

運行後的效果效果就是上面的預覽圖,咱們固然還能夠構建更復雜的狀況,WPF中基本上全部的控件,均可以定義控件模板。blog

上面的狀況是咱們針對一個按鈕重寫這樣的控件模板,若是咱們一個頁面中有多個控件,而且這些控件的樣式都是同樣的,惟一的區別是控件的內容或文本不一樣而已,咱們應該如何作呢?這個時候咱們就須要把控件模板定義爲資源,以下所示:事件

image

咱們下面添加多個按鈕,來看看應用的具體效果:

image

夠簡單吧,其實很簡單,咱們就能夠重寫控件的模板了,好了,下面來看看更復雜一些的,咱們可能想當鼠標滑過,或者按下後,按鈕有一個不一樣的樣式,這時候咱們就會涉及到前面介紹的Tigger了,下面咱們就來看看

image

具體的代碼以下:

image

在WPF中,爲了提升用戶體驗的效果,實現界面特殊的效果,咱們會大量的使用動畫來完成。

image

前面用了大量的篇幅來講明,控件模板和觸發器,實現界面的特殊的效果,使用WPF來作事很是的簡單。

在第二小節中,咱們將會舉幾個例子來講明項目中的具體用法。

 

數據模板

數據模板與控件模板不一樣,主要是針對某種類型的數據而定製的模板,該模板會自動根據綁定的數據類型,在構造界面顯示時,根據預先設定的數據模板來組織頁面顯示的內容。數據模板和控件模板的定義差很少。咱們先來定義一個數據模板,而後看看如何使用。

image

咱們來看看代碼是如何設定的,才能實現,這樣的效果:

image

上面用到了,綁定,關於更多的綁定,咱們在後面的MVVM的實例中大量的使用了綁定。

image

基於人員信息,構造人員信息綁定集合

image

將ViewModel與界面創建關聯關係

image

最後,採用ListBox來顯示數據項,經過數據綁定來實現

image

這裏咱們發現數據模板的效果,並非很是的好看,這時候,咱們能夠採用樣式模板來完成樣式設定。

image

而後咱們從新設置Listview的樣式後,運行:

image

F5運行後效果以下:

image

 

ListBox深度模板定製

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

定製Demo1

上面咱們雖然應用了樣式,可是仍是感受很差看,並且鼠標點擊後沒有效果,是由於在觸發器中沒有作任何的效果設定。

咱們若是在觸發器中修改成Button或者Border的背景色,再試試呢?

image

果真是咱們想要的效果,那麼咱們來看看咱們只須要在模板中書寫以下的簡單幾行代碼便可:

image

下面咱們先來看看一個效果。

image

ListView具備黑色的背景。能夠採用圖片或者顏色值

咱們將上面的例子,一步步的實現這個效果。

image

哈哈,就是這個效果,其實實現起來很是的簡單,就是重寫控件模板便可:

image

接着:重寫觸發器,當鼠標滑過期的樣式

當鼠標得到焦點也就是按下時的樣式。

image

設置Grid的樣式

image

只須要簡單的幾步,就徹底能夠實現一組特別不錯的效果。

上面咱們把樣式都寫到頁面當中了,對於具體的狀況,可能咱們但願可以將樣式通用,因此,咱們會定義一個單獨的樣式文件,關於樣式文件,咱們前面的文章中也有提到過,這裏就不作特別的說明了。

下面咱們來看看另外的一個效果:

image

對於這樣的效果,咱們也能夠經過ListBox來實現,無非就是重寫ListBox的控件模板

下面咱們也來一步步的分析下效果的實現

image

選中後的高亮效果,無非就是設置邊框。

而後就是橫向顯示,須要重寫ListBox的ItemsPanel修改成WrapPanel。

image

這樣,咱們的列表項就能夠橫向顯示,而後設置每一個列表項的樣式:

image

爲了可以看到Border的邊框,請設置borderThickness和顏色。

同時保持border內部的子控件與border的邊距值,不然出現不了,剛纔展現的效果。

image

代碼自己就是這些東西,都是比較簡單的。

TreeView高級模板使用實例

Treeview的效果

首先給你們看看實現的具體效果。

image

上面的效果,仍是不錯的,不過實現起來的難度就會大不少。

下面給出設計思路和具體的實現代碼。

image

咱們實現的效果如上圖,屏蔽了原始的+-符號,太難看了,因此,咱們重寫了相關的樣式和模板來達到上述的效果,下面給出具體的實現

A、先定義基本的ViewModel

image

具體的代碼,會提供下載

B、定義TreeView的數據庫結構

image

上面定義的ViewModel只是爲了DataTemplate使用的,在DataTemplate那裏一看就明白了。

image

修改原來的數據結構,如上。

添加一個負責界面綁定的ViewModel

public class PersonViewModelCollection : INotifyPropertyChanged 
   { 
       System.Collections.ObjectModel.ObservableCollection<ResourceSturctViewModel> persons = 
           new System.Collections.ObjectModel.ObservableCollection<ResourceSturctViewModel>();

       public PersonViewModelCollection() 
       { 
           Person tempA = new Person() 
           { 
               Address = "北京", 
               Name = "A", 
               Photo = "/Samples.04.Template;Component/Images/logo_small.gif", 
               Sex = "男" 
           };

           Person tempB = new Person() 
           { 
               Address = "北京", 
               Name = "B", 
               Photo = "/Samples.04.Template;Component/Images/logo_small.gif", 
               Sex = "未知" 
           };

           List<Person> tempABPersons = new List<Person>(); 
           tempABPersons.Add(tempA); 
           tempABPersons.Add(tempB); 
           Person[] tempPersons = tempABPersons.ToArray();

           persons.Add(new ResourceSturctViewModel(new Person() 
           { 
               Address = "北京", 
               Name = "A", 
               Photo = "/Samples.04.Template;Component/Images/logo_small.gif", 
               Sex = "男", 
               Childerns = tempPersons

           }));

           persons.Add(new ResourceSturctViewModel(new Person() 
           { 
               Address = "河北", 
               Name = "B", 
               Photo = "/Samples.04.Template;Component/Images/logo_small.gif", 
               Sex = "女", 
               Childerns = tempPersons 
           }));

           persons.Add(new ResourceSturctViewModel(new Person() 
           { 
               Address = "山西", 
               Name = "C", 
               Photo = "/Samples.04.Template;Component/Images/logo_small.gif", 
               Sex = "男", 
               Childerns = tempPersons 
           })); 
       }

       public System.Collections.ObjectModel.ObservableCollection<ResourceSturctViewModel> PersonList 
       { 
           get 
           { 
               return this.persons; 
           } 
       }

       #region INotifyPropertyChanged 成員

       public event PropertyChangedEventHandler PropertyChanged;

       #endregion 
   }

 

後臺的相關代碼,都構建完畢了,下面咱們就來看看界面的設計和組織了:

image

TreeView節點前的展開摺疊樣式

image

TrewViewItem的每一個節點項的樣式:

image

上面沒有設置具體的控件和綁定,而是經過ContentPresenter和ItemsHost來處理的,這樣咱們就能夠結合數據模板來作統一處理,最終將DataTemplate設置的控件自動顯示到當前的ContentPresenter和ItemsHost中。

image

若是不按照上述要求,那麼當咱們重寫TreeView時就會遇到不少莫名其妙的問題,我也是遇到了,才總結出來。

在前面的樣式中,咱們加入了以下事件,務必寫上,這是爲了觸發Lazyload的操做的。

image

等你本身試一遍,就會發現其實也不難,只要掌握了對自定義模板的規則,就徹底能夠自定義更復雜的樣式和效果。

相關文章
相關標籤/搜索