一:首先来看一下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. 2-postman批量执行接口

    1.postman环境设置与使用 1)点击设置,添加按钮 2)填写环境名称,参数 3)切换环境 4)使用环境变量,使用格式为:{{变量名}} 2.postman批量执行接口 1)选择要执行的文件夹,点 ...

  2. python3字符串操作

    python3字符串操作 x = 'abc' y = 'defgh' print(x + y) #x+y print(x * ) #x*n print(x[]) #x[i] print(y[:-]) ...

  3. R语言-编写自定义函数 ZZ

    一.函数构造器 每一个R函数都包括三个部分:函数名,程序主体以及参数集合,在编写自定义R函数时,需要将三个部分各自储存在一个R对象中.这里需要使用function函数,形如: my_function& ...

  4. .NET Core微服务之路:利用DotNetty实现一个简单的通信过程

    上一篇我们已经全面的介绍过<基于gRPC服务发现与服务治理的方案>,我们先复习一下RPC的调用过程(笔者会在这一节的几篇文章中反复的强调这个过程调用方案),看下图

  5. MVC 5使用TempData Object跨视图传递数据

    经过一系列显示数据的练习:<MVC 5使用ViewData(对象)显示数据>http://www.cnblogs.com/insus/p/3377178.html<MVC 5使用Vi ...

  6. [BOT]自定义ViewPagerStripIndicator

    效果图 app中下面这样的控件很常见,像默认的TabHost表现上不够灵活,下面就简单写一个可以结合ViewPager切换内容显示,提供底部"滑动条"指示所显示页签的效果. 这里控 ...

  7. MSRA-TD5000数据集使用详解

    中文检测的数据集,目前最火的应该是清华的CTW,https://ctwdataset.github.io/ 但是它的数据集只存储在微云和google driver,微云空间受限不能完全保存,所以下载的 ...

  8. [SRC初探]手持新手卡挖SRC逻辑漏洞心得分享

    文章来源i春秋 本文适合新手参阅,大牛笑笑就好了,嘿嘿末尾有彩蛋!!!!!!!!!!!!!!!!!本人参加了本次"i春秋部落守卫者联盟"活动,由于经验不足,首次挖SRC,排名不是那 ...

  9. JavaScript中的定时事件

    这两个函数都是在给定的时间之后开始执行的,并不是立即执行. var timeId = window.setTimeout("method()",1000); //定时执行,还可以这 ...

  10. Android Fragment用法知识点的讲解

    Android Fragment用法的讲解 碎片,它的出现是为了更好展示UI的设计,让程序更加得到充分的展示.Fragment的出现,如微信的额主界面包含多个Fragment,使得微信功能更加简洁明了 ...