一、控件模板及數據模板數據庫
二、ListBox深度定製模板。數據結構
三、TreeView高級模板使用實例。性能
什麼是控件模板,指定能夠在控件的多個實例之間共享 Control 的可視結構和性能方面的方面。控件模板其實就是咱們在可視方面的自定義模板,ControlTemplate 容許您指定控件的可視結構。 重寫 ControlTemplate 從新生成該控件的可視結構。動畫
模板化控件是 WPF 提供的許多功能之同樣式設置和模板化模型。 該樣式和模板化模型提供了許多狀況下您不須要編寫擁有控件這樣的大的靈活性。this
控件模板包含二方面的內容:VisualTree和Tigger。本篇介紹的內容,徹底都是基於這二塊的內容進行討論和說明。spa
VisualTree就是對應WPF控件的可視元素的定義,下面來舉例說明:設計
上面,咱們經過了lable重寫了button按鈕的控件模板,咱們還能夠採用更復雜的控件來重寫它:3d
運行後的效果效果就是上面的預覽圖,咱們固然還能夠構建更復雜的狀況,WPF中基本上全部的控件,均可以定義控件模板。blog
上面的狀況是咱們針對一個按鈕重寫這樣的控件模板,若是咱們一個頁面中有多個控件,而且這些控件的樣式都是同樣的,惟一的區別是控件的內容或文本不一樣而已,咱們應該如何作呢?這個時候咱們就須要把控件模板定義爲資源,以下所示:事件
咱們下面添加多個按鈕,來看看應用的具體效果:
夠簡單吧,其實很簡單,咱們就能夠重寫控件的模板了,好了,下面來看看更復雜一些的,咱們可能想當鼠標滑過,或者按下後,按鈕有一個不一樣的樣式,這時候咱們就會涉及到前面介紹的Tigger了,下面咱們就來看看
具體的代碼以下:
在WPF中,爲了提升用戶體驗的效果,實現界面特殊的效果,咱們會大量的使用動畫來完成。
前面用了大量的篇幅來講明,控件模板和觸發器,實現界面的特殊的效果,使用WPF來作事很是的簡單。
在第二小節中,咱們將會舉幾個例子來講明項目中的具體用法。
數據模板與控件模板不一樣,主要是針對某種類型的數據而定製的模板,該模板會自動根據綁定的數據類型,在構造界面顯示時,根據預先設定的數據模板來組織頁面顯示的內容。數據模板和控件模板的定義差很少。咱們先來定義一個數據模板,而後看看如何使用。
咱們來看看代碼是如何設定的,才能實現,這樣的效果:
上面用到了,綁定,關於更多的綁定,咱們在後面的MVVM的實例中大量的使用了綁定。
基於人員信息,構造人員信息綁定集合
將ViewModel與界面創建關聯關係
最後,採用ListBox來顯示數據項,經過數據綁定來實現
這裏咱們發現數據模板的效果,並非很是的好看,這時候,咱們能夠採用樣式模板來完成樣式設定。
而後咱們從新設置Listview的樣式後,運行:
F5運行後效果以下:
上面咱們雖然應用了樣式,可是仍是感受很差看,並且鼠標點擊後沒有效果,是由於在觸發器中沒有作任何的效果設定。
咱們若是在觸發器中修改成Button或者Border的背景色,再試試呢?
果真是咱們想要的效果,那麼咱們來看看咱們只須要在模板中書寫以下的簡單幾行代碼便可:
下面咱們先來看看一個效果。
ListView具備黑色的背景。能夠採用圖片或者顏色值
咱們將上面的例子,一步步的實現這個效果。
哈哈,就是這個效果,其實實現起來很是的簡單,就是重寫控件模板便可:
接着:重寫觸發器,當鼠標滑過期的樣式
當鼠標得到焦點也就是按下時的樣式。
設置Grid的樣式
只須要簡單的幾步,就徹底能夠實現一組特別不錯的效果。
上面咱們把樣式都寫到頁面當中了,對於具體的狀況,可能咱們但願可以將樣式通用,因此,咱們會定義一個單獨的樣式文件,關於樣式文件,咱們前面的文章中也有提到過,這裏就不作特別的說明了。
下面咱們來看看另外的一個效果:
對於這樣的效果,咱們也能夠經過ListBox來實現,無非就是重寫ListBox的控件模板
下面咱們也來一步步的分析下效果的實現
選中後的高亮效果,無非就是設置邊框。
而後就是橫向顯示,須要重寫ListBox的ItemsPanel修改成WrapPanel。
這樣,咱們的列表項就能夠橫向顯示,而後設置每一個列表項的樣式:
爲了可以看到Border的邊框,請設置borderThickness和顏色。
同時保持border內部的子控件與border的邊距值,不然出現不了,剛纔展現的效果。
代碼自己就是這些東西,都是比較簡單的。
首先給你們看看實現的具體效果。
上面的效果,仍是不錯的,不過實現起來的難度就會大不少。
下面給出設計思路和具體的實現代碼。
咱們實現的效果如上圖,屏蔽了原始的+-符號,太難看了,因此,咱們重寫了相關的樣式和模板來達到上述的效果,下面給出具體的實現
A、先定義基本的ViewModel
具體的代碼,會提供下載
B、定義TreeView的數據庫結構
上面定義的ViewModel只是爲了DataTemplate使用的,在DataTemplate那裏一看就明白了。
修改原來的數據結構,如上。
添加一個負責界面綁定的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
}
後臺的相關代碼,都構建完畢了,下面咱們就來看看界面的設計和組織了:
TreeView節點前的展開摺疊樣式
TrewViewItem的每一個節點項的樣式:
上面沒有設置具體的控件和綁定,而是經過ContentPresenter和ItemsHost來處理的,這樣咱們就能夠結合數據模板來作統一處理,最終將DataTemplate設置的控件自動顯示到當前的ContentPresenter和ItemsHost中。
若是不按照上述要求,那麼當咱們重寫TreeView時就會遇到不少莫名其妙的問題,我也是遇到了,才總結出來。
在前面的樣式中,咱們加入了以下事件,務必寫上,這是爲了觸發Lazyload的操做的。
等你本身試一遍,就會發現其實也不難,只要掌握了對自定義模板的規則,就徹底能夠自定義更復雜的樣式和效果。