WPF Step By Step 自定义模板

回顾

上一篇,我们简单介绍了几个基本的控件,本节我们将讲解每个控件的样式的自定义和数据模板的自定义,我们会结合项目中的具体的要求和场景来分析,给出我们实现的方案和最终的运行效果。

本文大纲

1、控件模板及数据模板

2、ListBox深度定制模板。

3、TreeView高级模板使用实例。

控件模板及数据模板

控件模板

什么是控件模板,指定可以在控件的多个实例之间共享 Control 的可视结构和性能方面的方面。控件模板其实就是我们在可视方面的自定义模板,ControlTemplate 允许您指定控件的可视结构。 重写 ControlTemplate 重新生成该控件的可视结构。

模板化控件是 WPF 提供的许多功能之一样式设置和模板化模型。 该样式和模板化模型提供了许多情况下您不需要编写拥有控件这样的大的灵活性。

控件模板包含二方面的内容:VisualTree和Tigger。本篇介绍的内容,完全都是基于这二块的内容进行讨论和说明。

什么是ViewTree

VisualTree就是对应WPF控件的可视元素的定义,下面来举例说明:

上面,我们通过了lable重写了button按钮的控件模板,我们还可以采用更复杂的控件来重写它:

运行后的效果效果就是上面的预览图,我们当然还可以构建更复杂的情况,WPF中基本上所有的控件,都可以定义控件模板。

上面的情况是我们针对一个按钮重写这样的控件模板,如果我们一个页面中有多个控件,并且这些控件的样式都是一样的,唯一的区别是控件的内容或文本不同而已,我们应该如何做呢?这个时候我们就需要把控件模板定义为资源,如下所示:

我们下面添加多个按钮,来看看应用的具体效果:

够简单吧,其实很简单,我们就可以重写控件的模板了,好了,下面来看看更复杂一些的,我们可能想当鼠标滑过,或者按下后,按钮有一个不同的样式,这时候我们就会涉及到前面介绍的Tigger了,下面我们就来看看

具体的代码如下:

在WPF中,为了提高用户体验的效果,实现界面特殊的效果,我们会大量的使用动画来完成。

前面用了大量的篇幅来说明,控件模板和触发器,实现界面的特殊的效果,使用WPF来做事非常的简单。

在第二小节中,我们将会举几个例子来说明项目中的具体用法。

数据模板

数据模板与控件模板不同,主要是针对某种类型的数据而定制的模板,该模板会自动根据绑定的数据类型,在构造界面显示时,根据预先设定的数据模板来组织页面显示的内容。数据模板和控件模板的定义差不多。我们先来定义一个数据模板,然后看看如何使用。

我们来看看代码是如何设定的,才能实现,这样的效果:

上面用到了,绑定,关于更多的绑定,我们在后面的MVVM的实例中大量的使用了绑定。

基于人员信息,构造人员信息绑定集合

将ViewModel与界面建立关联关系

最后,采用ListBox来显示数据项,通过数据绑定来实现

这里我们发现数据模板的效果,并不是非常的好看,这时候,我们可以采用样式模板来完成样式设定。

然后我们重新设置Listview的样式后,运行:

F5运行后效果如下:

ListBox深度模板定制

定制Demo1

上面我们虽然应用了样式,但是还是感觉不好看,而且鼠标点击后没有效果,是因为在触发器中没有做任何的效果设定。

我们如果在触发器中修改为Button或者Border的背景色,再试试呢?

果然是我们想要的效果,那么我们来看看我们只需要在模板中书写如下的简单几行代码即可:

下面我们先来看看一个效果。

ListView具有黑色的背景。可以采用图片或者颜色值

我们将上面的例子,一步步的实现这个效果。

哈哈,就是这个效果,其实实现起来非常的简单,就是重写控件模板即可:

接着:重写触发器,当鼠标滑过时的样式

当鼠标获得焦点也就是按下时的样式。

设置Grid的样式

只需要简单的几步,就完全可以实现一组特别不错的效果。

上面我们把样式都写到页面当中了,对于具体的情况,可能我们希望能够将样式通用,所以,我们会定义一个单独的样式文件,关于样式文件,我们前面的文章中也有提到过,这里就不做特别的说明了。

下面我们来看看另外的一个效果:

对于这样的效果,我们也可以通过ListBox来实现,无非就是重写ListBox的控件模板

下面我们也来一步步的分析下效果的实现

选中后的高亮效果,无非就是设置边框。

然后就是横向显示,需要重写ListBox的ItemsPanel修改为WrapPanel。

这样,我们的列表项就可以横向显示,然后设置每个列表项的样式:

为了能够看到Border的边框,请设置borderThickness和颜色。

同时保持border内部的子控件与border的边距值,否则出现不了,刚才展示的效果。

代码本身就是这些东西,都是比较简单的。

TreeView高级模板使用实例

Treeview的效果

首先给大家看看实现的具体效果。

上面的效果,还是不错的,不过实现起来的难度就会大很多。

下面给出设计思路和具体的实现代码。

我们实现的效果如上图,屏蔽了原始的+-符号,太难看了,所以,我们重写了相关的样式和模板来达到上述的效果,下面给出具体的实现

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的操作的。

等你自己试一遍,就会发现其实也不难,只要掌握了对自定义模板的规则,就完全可以自定义更复杂的样式和效果。

WPF Step By Step 自定义模板的更多相关文章

  1. WPF Step By Step 系列 - 开篇 ·

    WPF Step By Step 系列 - 开篇 公司最近要去我去整理出一个完整的WPF培训的教程,我刚好将自己学习WPF的过程和经验总结整理成笔记的方式来讲述,这里就不按照书上面的东西来说了,书本上 ...

  2. WPF Step By Step 系列-Prism框架在项目中使用

    WPF Step By Step 系列-Prism框架在项目中使用 回顾 上一篇,我们介绍了关于控件模板的用法,本节我们将继续说明WPF更加实用的内容,在大型的项目中如何使用Prism框架,并给予Pr ...

  3. WPF Step By Step 完整布局介绍

    WPF Step By Step 完整布局介绍 回顾 上一篇,我们介绍了基本控件及控件的重要属性和用法,我们本篇详细介绍WPF中的几种布局容器及每种布局容器的使用场景,当 然这些都是本人在实际项目中的 ...

  4. WPF Step By Step 控件介绍

    WPF Step By Step 控件介绍 回顾 上一篇,我们主要讨论了WPF的几个重点的基本知识的介绍,本篇,我们将会简单的介绍几个基本控件的简单用法,本文会举几个项目中的具体的例子,结合这些 例子 ...

  5. WPF MVVM 架构 Step By Step(6)(把actions从view model解耦)

    到现在为止,我们创建了一个简单的MVVM的例子,包含了实现了的属性和命令.我们现在有这样一个包含了例如textbox类似的输入元素的视图,textbox用绑定来和view model联系,像点击but ...

  6. SharePoint 2013 Step by Step——使用自定义的List Template

    Overview 对于企业员工来说,"扁平结构"的LIST是日常操作中经常使用到的,LIST的好处是方便数据的录入以及数据的整理分析,尤其是Quick Edit功能,可以实现快速编 ...

  7. Linkerd 2.10(Step by Step)—使用 Kustomize 自定义 Linkerd 的配置

    Linkerd 2.10 系列 快速上手 Linkerd v2 Service Mesh(服务网格) 腾讯云 K8S 集群实战 Service Mesh-Linkerd2 & Traefik2 ...

  8. .NET/ASP.NETMVC Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(一)

    .NET/ASP.NETMVC Model元数据.HtmlHelper.自定义模板.模板的装饰者模式(一) 阅读目录: 1.开篇介绍 2.Model与View的使用关系(数据上下文DataContex ...

  9. [py]python写一个通讯录step by step V3.0

    python写一个通讯录step by step V3.0 参考: http://blog.51cto.com/lovelace/1631831 更新功能: 数据库进行数据存入和读取操作 字典配合函数 ...

随机推荐

  1. Java--常用类summary(二)

    /* 1:StringBuffer(掌握) (1)用字符串做拼接,比较耗时并且也耗内存,而这种拼接操作又是比较常见的,为了解决这个问题,Java就提供了 一个字符串缓冲区类.StringBuffer供 ...

  2. 449. Serialize and Deserialize BST——几乎所有树的面试题目都会回到BFS或者DFS,使用BFS,None节点存#

    Serialization is the process of converting a data structure or object into a sequence of bits so tha ...

  3. 百度Tera数据库介绍——类似cassandra,levelDB

    转自:https://my.oschina.net/u/2982571/blog/775452 设计背景 百度的链接处理系统每天处理万亿级的超链数据,在过去,这是一系列Mapreduce的批量过程,对 ...

  4. 用户列表-投资记录sql

    --普通标.定向标.新手标.老互融计划-投资记录表select bid.borrow_id, (select yyb.borrow_valid_time from YYD_Borrow_BorrowI ...

  5. Phonegap hello world 不容易啊~!

    今天一个项目要用phonegap,当初就是觉得phonegap配置太tmd的麻烦了,所以转头appcan,但今天项目必须用-- 先是看到官方说用nodejs装,tmd的,总是重复同一个错误,安装不起, ...

  6. HDU 4050 wolf5x 概率dp 难度:1

    http://acm.hdu.edu.cn/showproblem.php?pid=4050 题意: 现在主角站在0处,需要到达大于n的位置 主角要进入的格子有三种状态: 0. 不能进入 1. 能进入 ...

  7. 使用plsql连接别人的oracle(转)

    文章来源:http://www.linuxidc.com/Linux/2013-04/82738.htm oracle服务有时候我们觉得太大,所以我们只需要在本机上装一个oracle客户端和plsql ...

  8. 常错-UIScrollView中得图片不能被拖动

    经常在开发中,发现自己UIScrollView里面的图片不能被拖动 在这里做个备忘,第一种可能是contentSize没有设置,第二种可能是contentSize设置的太小了. 测试后发现,与user ...

  9. iphone获取当前运行进程列表

    通过调用 sys/sysctl.h 读取系统内核获取进程列表 . 代码悦德财富:https://yuedecaifu.com 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 ...

  10. windows azure中国 里面建立一个虚拟机,与虚拟机建立通信 里面部署IIS,外网访问

    在windows azure中国 里面建立一个虚拟机,里面部署IIS,外网不能访问么? 外网访问的地址是给的那个DNS地址 ,比如我的是 DNS 名称 urbanairserver.cloudapp. ...