开发者社区> 余二五> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

WPF感悟(3)——关于向窗体动态添加控件

简介:
+关注继续查看
WPF感悟(3)——关于向窗体动态添加控件
这是一个很有意思的话题。
首先,虽然在讲课的时候,我时常会讲到一些关于动态地向窗体中添加控件的例子,但在实际工作中我却很少用用到要这个技术。一般情况下,控件在窗体上是写好的,只是根据需要显示与隐藏。
其次,也是最重要的——我标题用的是“窗体”没有用Window,这是为什么呢?因为同样看上去是窗体,WinForm编程对应的类是Form,WPF编程对应的类是Window。虽然在运行时(run time)它们都是Windows API用CreateWindowEx函数创建出来的Window Class,但在它们还是.NET类的时候,却有着巨大的区别——特别是体现在内部控件的组织形式上。
WinForm
WinForm窗体里的按钮、文本框等供用户操作的对象称为“控件”(controls)。这些控件可以分为两类,一类是非容器控件,这类控件的内部结构是固定不变的,比如一个Button内部只能是一串文字(还可以设置Button的背景图片),如果你想在Button内显示一个图标后跟上一串文字,要么你写一个自定义控件(派生自Button、再来点儿GDI+的技术)、要么你把文字写在图片上整个作为Button的背景图片;另一类是容器控件,它的内部可以装一些其他控件,这类控件的一个特点就是有一个Controls属性,这是一个ControlCollection。
你可以把Form也看成是一个容器控件。我们说的动态添加控件也就是向容器控件内添加控件了——方法就是先声明一个与控件类型相对应的变量、为它创建一个控件类型的实例、把这个实例初始化好之后再调用Contols.Add方法,把这个变量添加进容器控件就好了。看起来大概是这样:
  1. private void button1_Click(object sender, EventArgs e)   
  2. {   
  3.     Button button = new Button();   
  4.     button.Size = new Size(80, 20);   
  5.     button.Text = "OK";   
  6.     groupBox1.Controls.Add(button);   
  7. }  
这里有两点非常重要——
  • WinForm的控件组织是“平面化”的,也就是说,在一个容器控件内,它们处在同一个ControlCollection内、不再有包含关系(除非它是一个容器控件)。如果我们把目光放的宏观一些,那么WinForm窗体在包含容器控件时,可以称之为一棵以容器控件(也只能以容器控件)为结点的、逻辑上的树——但实际工作中我们谁也不会去使用这棵树,因为它没什么用处。后面你会看到,WPF里也有“树”——那是真正的树,WPF几乎一切事件消息路由都依赖于这棵树。
  • 要想向Controls里添加一个初始化完备的控件,你就几乎总要声明一个变量——在WPF里就不用这么做,因为XAML本身的树状结构,再加上新版本.NET支持“对象初始化”语法,使代码变得非常简单。当然,.NET的方便的功能并非WPF所独享的——我们完全可以在WinForm编程中也使用它,上面的代码会简化成这样
  1. private void button1_Click(object sender, EventArgs e)   
  2. {   
  3.     groupBox1.Controls.Add(new Button { Text = "OK", Size = new Size(80,20) });   
  4. }  
这种语法叫做“对象初始化器”,这也是我要在下一篇文章——《WPF感悟(4)——对象初始化器传奇》——里将要介绍的内容。
WPF
WPF窗体里的按钮、文本框等UI组件称为“元素”(Element),更确切地说是“UI元素”(与UIElement类对应)。UI元素这个词里隐含了一点,那就是:它一定是“可视”的(Visual),不然怎么让用户去使用呢?
WPF UI元素与WinForm控件最大的不同就是WPF UI元素不再以“容器”和“非容器”作为区分,而是以“内容元素”和“非内容元素”来区分。所谓内容元素,就是说它有一个名为Content的属性——它是Object类型的!要知道,Object类是所有.NET类的父类,这就意味着对于一个内容元素来说,随便你往它里面装什么都可以!装一个UI元素可以、装一组UI元素也可以——把这组元素组合在一个集合里就OK了。
如果内容元素的内容仍然是内容元素呢?一棵真正的、可视化的“树”就形成了。这就是WPF中声明赫赫的Visual Tree,WPF窗体上的事件消息也是沿着这棵可视化树传递的——消息经过每个可视化树上的结点(UIElement)时称为“路由”(Route),这时候我们可以对消息进行处理和控制。这方面的知识我将在《深入浅出WPF》系列文章里仔细介绍。
你可能会问,WPF里有哪些UIElement是Content Element呢?呃……真问住我了。太多了!以至于我只记得几个非Content Element——比如TextBlock、TextBox。在WPF中,非Content Element的表现功能是很弱的,因为它们肚子里的内容太单一了。就拿TextBlock和TextBox来说,它们的内容只能是文本。
Content Element的内容就非常多了!Button就是一个Content元素。在WPF中,Button摇身一变,肚子里可就“别有洞天”了。
……打会儿游戏,晚上接着写。









本文转自 水之真谛 51CTO博客,原文链接:http://blog.51cto.com/liutiemeng/95270,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
WPF自定义控件与样式(8)-ComboBox与自定义多选控件MultComboBox
原文:WPF自定义控件与样式(8)-ComboBox与自定义多选控件MultComboBox 一.前言   申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接。
974 0
在WPF的WebBrowser控件中抑制脚本错误
原文:在WPF的WebBrowser控件中抑制脚本错误 今天用WPF的WebBrowser控件的时候,发现其竟然没有ScriptErrorsSuppressed属性,导致其到处乱弹脚本错误的对话框,在MSDN上找到了如下解决方案:  1 static void SuppressScriptE...
693 0
WPF下可编辑Header的Tab控件实现
介绍 有这样一个需求,当用户双击Tab控件Header区域时, 希望可以直接编辑。对于WPF控件,提供一个ControlTemplate在加上一些Trigger就可以实现。效果如下: 代码 首先,我们需要给Tab Header设计一个ControlTemplate。
511 0
WPF中实现多选ComboBox控件
原文:WPF中实现多选ComboBox控件 在WPF中实现带CheckBox的ComboBox控件,让ComboBox控件可以支持多选。 将ComboBox的ItemsSource属性Binding到一个Book的集合, public class Book { ...
1523 0
WPF 4 DataGrid 控件(基本功能篇)
原文:WPF 4 DataGrid 控件(基本功能篇)      提到DataGrid 不管是网页还是应用程序开发都会频繁使用。通过它我们可以灵活的在行与列间显示各种数据。本篇将详细介绍WPF 4 中DataGrid 的相关功能。
577 0
WPF 控件库——仿制Windows10的进度条
原文:WPF 控件库——仿制Windows10的进度条 一、其实有现成的   先来看看Windows10进度条的两种模式:       网上有不少介绍仿制Windows10进度条的文章,也都实现了不错的效果。
693 0
WPF 控件库——仿制Chrome的ColorPicker
原文:WPF 控件库——仿制Chrome的ColorPicker 一、观察   项目中的一个新需求,需要往控件库中添加颜色拾取器控件,因为公司暂时还没有UI设计大佬入住,所以就从网上开始找各种模样的ColorPicker,找来找去我就看上了谷歌浏览器自带的,它长这个样:         看上去不错,可以搞!搞之前得观察一下这里面可能的一些坑。
1041 0
+关注
文章
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载