一:首先来看一下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。

UserControl VS TemplatedControl的更多相关文章

  1. [UWP]了解模板化控件(5.2):UserControl vs. TemplatedControl

    1. UserControl vs. TemplatedControl 在UWP中自定义控件常常会遇到这个问题:使用UserControl还是TemplatedControl来自定义控件. 1.1 使 ...

  2. [UWP 自定义控件]了解模板化控件(5.2):UserControl vs. TemplatedControl

    1. UserControl vs. TemplatedControl 在UWP中自定义控件常常会遇到这个问题:使用UserControl还是TemplatedControl来自定义控件. 1.1 使 ...

  3. [UWP]了解模板化控件(1):基础知识

    1.概述 UWP允许开发者通过两种方式创建自定义的控件:UserControl和TemplatedControl(模板化控件).这个主题主要讲述如何创建和理解模板化控件,目标是能理解模板化控件常见的知 ...

  4. UWP 自定义控件:了解模板化控件 系列文章

    UWP自定义控件的入门文章 [UWP 自定义控件]了解模板化控件(1):基础知识 [UWP 自定义控件]了解模板化控件(2):模仿ContentControl [UWP 自定义控件]了解模板化控件(2 ...

  5. [UWP 自定义控件]了解模板化控件(1):基础知识

    1.概述 UWP允许开发者通过两种方式创建自定义的控件:UserControl和TemplatedControl(模板化控件).这个主题主要讲述如何创建和理解模板化控件,目标是能理解模板化控件常见的知 ...

  6. 一种开发模式:ajax + ashx + UserControl

    一.ajax+ashx模式的缺点     在web开发过程中,为了提高网站的用户体验,或多或少都会用到ajax技术,甚至有的网站全部采用ajax来实现,大量使用ajax在增强用户体验的同时会带来一些负 ...

  7. Wpf usercontrol dispose

    窗口关闭时组件"析构": public UserControl()        {            InitializeComponent();               ...

  8. XAML UserControl的继承

    欢迎访问Heroius博客:崩溃的脑壳查看文章原文! 前言 相信不少学习WPF和Silverlight的同学们都出于Winform的习惯,希望能够在新展示层框架中实现控件的继承.本文就是说明如何实现这 ...

  9. wpf的UserControl用户控件怎么添加到Window窗体中

    转载自 http://www.cnblogs.com/shuang121/archive/2013/01/09/2853591.html 我们来新建一个用户控件UserControl1.xaml &l ...

随机推荐

  1. php SQL 防注入的一些经验

    产生原因 一方面自己没这方面的意识,有些数据没有经过严格的验证,然后直接拼接 SQL 去查询.导致漏洞产生,比如: $id = $_GET['id']; $sql = "SELECT nam ...

  2. Windows核心编程:第10章 同步设备IO与异步设备IO

    Github https://github.com/gongluck/Windows-Core-Program.git //第10章 同步设备IO与异步设备IO.cpp: 定义应用程序的入口点. // ...

  3. [.net core学习] .net core中的Rijndael取代方法

    The difference (in .NET) between Rijndael and AES is that Rijndael allows the block size to change, ...

  4. Scala + IntelliJ IDEA

    学习路上的新起点:大数据Scala + Spark +(HDFS + HBase),本文主要介绍下Scala的基本语法和用法吧.最后再简单介绍一种Java开发工具IntelliJ IDEA的使用. S ...

  5. lable标签的用途

    lable标签的用途:为iput输入框元素定义标注: label 元素不会向用户呈现任何特殊效果.不过,它为鼠标用户改进了可用性.如果您在 label 元素内点击文本,就会触发此控件.就是说,当用户选 ...

  6. Base 64 加密、解密

    1.写一个公共类 package com.boyutec.oss.sys.utils; import java.io.UnsupportedEncodingException; import java ...

  7. Java Web——过滤器

    <Java Web开发技术应用——过滤器> 过滤器是一个程序,它先于与之相关的servlet或JSP页面运行在服务器上.过滤器可附加到一个或多个servlet或JSP页面上,并且可以检查进 ...

  8. springboot创建统一异常拦截器全局处理 异常

    1.创建Exception类 public class MyException extends RuntimeException { private ErrorCodeEnum errorCode; ...

  9. SQL Server性能优化(11)非聚集索引的覆盖索引存储结构

    一,非聚集索引的include 非聚集索引的Include属性可以让非聚集索引包含其他列.如 CREATE NONCLUSTERED INDEX [NonIxUser] ON [dbo].[Users ...

  10. window傻瓜式安装tensorflow

    最近学习一下,比较热门的深度学习. 本人英文差,记性差,什么都差,哈哈. 折腾过ub安装,虽然成功,但是总是觉得不好用. 发现tenorflow已经可以很傻瓜的在windows下安装了....... ...