你的位置:首页 > ASP.net教程

[ASP.net教程]请正确使用UserControl和TemplatedControl


一:首先来看一下UserControl

     熟悉XAML的朋友们都知道,当我们创建一个用户控件的时候,VS会自动为我们生成一个XXX.xaml文件和XXX..xaml.cs文件,XAML文件用于进行控件的UI界面设计,对应的CS文件则是进行逻辑代码的编写。我们主要看一下CS文件,打开CS文件,我们会发现我们自己创建的自定义控件继承自UserControl(别忘了对应的XAML中也是以UserControl为根结点),我们可以按下F12键来看一下UserControl:

      我们可以明显的看到UserControl继承了一个“Control”类和一个“IUserControl”接口,我们暂时只看“IUserControl”接口。继续F12它,看看它到底是什么东西:

里面很简单,就只有一个Content字段,但不要大意,它可是UIElement类型的哦!:),不明白它是干什么的话,不着急,我们可以看一下” UserControl “中的东西:

这下明白了吧,我们能够在自定义用户控件中直接写控件多亏有了它。这就有点类似于让你创建一个简单的图片按钮。

     SDK中是这样描述UserControl的:为定义一个封装相关的现有控件并提供其自身逻辑的新控件提供基类。简单理解就是为新控件定义基类,但这个新控件是有限定的,即是在现有控件的基础上创建的。这表明使用UserControl来创建自定义控件并不是很强大,它只能满足基本的自定义控件的需求。如果你的自定义控件只是几个现有控件的堆砌,样式的简单修改,属性事件的简单注册,它还是能满足你的需求,但是你想更加深入的修改那就没有想象中那么简单,比如你想卸载掉一些你自定义控件不支持但UserControl已经为你注册了的事件,这无疑是画蛇添足了!

      这就好比你要盖房子,微软已经为你把最大众的房屋骨架搭建好了。厨房、卧室、客厅什么的都为你设定好位置,你就按照这个来,具体内部怎么装修你自己看着办他不管,但是你想把厨房的位置挪到客厅,客厅的位置挪到卧室,建自己的小别墅,他允许你建,但后果自负,并且工作量也挺大的。哎,不说了,想想都可怕!要是你的房子,你愿意这样折腾吗?

二:其次来看一下TemplatedControl

      TemplatedControl是名副其实的自定义控件,它做到了真正的自定义,它要比UserControl更加的灵活。它只为你提供了作为一个控件最基本的属性和方法。所以你现在真是在以“小米加步枪”的装备来进行自定义控件。

      当我们创建一个CustomControl的时候,VS会自动为我们创建一个XXX.cs文件和一个位于在Themes文件夹下的Generic.xaml文件。Generic.xaml文件主要是自定义控件的样式编写,但它的编写不同于普通的XAML文件,它是以样式的语法格式来进行编写。

 

     看上面这段代码我们可以明显的注意到这个自定义控件是通过Style的方式来进行编写,TargetType表明我们需要对哪个声明的自定义控件进行样式的编写,ControlTemplate表明我们是要进行控件模板样式的设计,然后Border里面的元素就是你需要进行的样式设置。这个文件中的代码基本上没多大问题,但需要注意的问题是,由于Generic.xaml是一个样式文件,因此VS并不能为你实时展示它的样子。

接下来看一下我们创建的CustomControl.cs文件:

代码很简单,就仅仅一个构造函数,里面加了一句声明该控件默认的样式。我们看一下它的基类:Control,它与用户控件在后台代码方面最明显的一个区别就是它只继承了Control基类,而没有继承IUserControl接口,因此它里面是没办法直接放控件。像下面的这段代码这样写就是错误的:

      至于怎么解决不是本文的重点,感兴趣的朋友可以自行百度,我们继续往下说。通过上图我们还发现一个问题,就是XAML设计器已经将我们自己定义的自定义控件看作最小的控件单位,不允许其再嵌套子控件,不管你内部实现多么复杂,在我外部看来就是一个整体。由于我们的自定义控件只继承了Control,所以我们有时候不得不自己定义一些属性、方法和事件,这并不是什么坏事,我们也可以因此更好的进行自定义控件。

      SDK中是这样描述Control的:表示UI元素的基类,这些元素可使用ControlTemplate来定义其外观。用于ContentControlUserControlItemsControl和几个实际控件的父级类。这句话就不难理解了吧,它的适用范围要远远大于UserControl。进一步提高了在编写自定义控件的灵活性。

     这就好比你要盖房子,微软已经给你准备好了盖房子需要的基本原料,但他没有给你搭建房屋的骨架,除了原料你不用担心,其余什么你都需要自己搞定。至于房子盖成什么样要看你的能力。

三:建议

      如果一个Page中的控件较多,各种各样的控件都有,布局也相对麻烦,你会怎么处理页面布局?难道要都写到一个XAML文件中吗?如果代码少还可以接受,但是一不小心写了上千行怎么办?所以这个时候合理使用用户控件和模板控件不失为一种理想的选择。下图是我个人在使用中的布局规则,仅供参考:

三:总结

      就像Tony Champion(MVP)说的那样:UserControls are easier to create and maintain.  However, custom controls are more flexible. 既然鱼和熊掌不能兼得,那就要看你的选择。在实际项目中,常常会将几个普通的控件放到一个用户控件中,这样便于维护。但是如果让你 “从无到有”写一个相对复杂的控件,里面的逻辑要远远比普通控件复杂,你依然会选择使用用户控件吗?在我看来,UserControl属于创建方便管理类型的控件,而TemplatedControl才是真正意义上创建自定义控件。UserControl能做到的事情TemplatedControl也能做到,但TemplatedControl能做到的事情UserControl不一定能做到。简而言之:当你有多个简单控件需要多次组合复用,建议使用userControl,当你需要完完全全编写一个自定义控件,建议使用TemplatedControl。