一、控件模板及数据模板数据库
二、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的操做的。
等你本身试一遍,就会发现其实也不难,只要掌握了对自定义模板的规则,就彻底能够自定义更复杂的样式和效果。