zoukankan      html  css  js  c++  java
  • WPF学习笔记-自定义模板

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

    image

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

    image

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

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

    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

     转https://www.cnblogs.com/hegezhou_hot/archive/2012/10/29/2744197.html

  • 相关阅读:
    梦断代码阅读笔记03
    第十二周进度条
    找“水王”
    梦断代码阅读笔记02
    梦断代码阅读笔记01
    团队开发第二阶段个人博客(2)
    团队开发第二阶段个人博客(1)
    个人总结
    第16周学习进度条
    个人进度条第15周
  • 原文地址:https://www.cnblogs.com/anyihen/p/12919734.html
Copyright © 2011-2022 走看看