Silverlight最强大的地方就在于定义控件了,Silverlight提供了非常灵活和高效的控件定义方式,几乎可以实现任何复杂的控件实现,对于快速开发应用程序有着重要的意义。在Silverlight中一般将控件分为两大类:

  • 非ItemsControl,像TextBox、Button等,表示单一的一个控件,这样的控件大部分开发者都可以很好的理解和掌握
  • ItemsControl,像ListBox、ComboBox、TreeView等,用来承载多个控件,这样的控件给很多开发者带来困惑,不是很好理解,尤其是在定义ItemsControl控件时。希望通过本文能够让所有还对ItemsControl有困惑的开发者,能够更清晰的认识ItemsControl

那些困惑

  • 现在有如下的需求:我想添加如下的一个集合控件,期望选中项出现三角箭头的提示,应该是在DataTemplate中定义,还是在ListBoxItem中Template定义?
  • 下面的代码是如何实现多级数据绑定的,明明只使用了一级的DataTemplate?
    <sdk:HierarchicalDataTemplate x:Key="DataTemplate1" ItemsSource="{Binding SubFolders}">
    <Grid>
    <TextBlock TextWrapping="Wrap" Text="{Binding FolderName}"/>
    </Grid>
    </sdk:HierarchicalDataTemplate>

ItemsControl剖析

这里着重介绍其中几个关键方法,透彻理解这些方法是使用和定义ItemsControl的关键:

  • IsItemItsOwnContainerOverride,ItemsControl会遍历Items集合,对每个item调用该方法(注:对于设置ItemsSource的话,最终都会将ItemsSource中的每一项都添加到Items集合中),如果item类型和ItemsControl的每个Item的Container类型不匹配,返回false,否则返回true,如果要实现自定义的集合控件,这里就是该集合控件需要的ItemContainer类型。下图是ListBox中该方法的实现:
     
  • GetContainerForItemOverride,如果IsItemItsOwnContainerOverride返回false,就执行该方法,这个方法主要是为ItemsControl的每个Item返回一个ItemContainer对象
  • PrepareContainerForItemOverride,这个方法在准备显示每个Item之前做的一系列的准备工作,最主要的操作包括:
    1. 就是设置每个ItemContainer的ContentTemplate,这里也说明ItemContainer一般都为ContentControl,否则ItemsControl的ItemTemplate设置就没有任何意义
    2. 如果ItemsControl设置了DisplayMemberPath的话,ItemsControl就生成一个DisplayMemberTemplate的内部类,这个类本质上是一个DataTemplate,从DataTemplate继承,其使用TextBlock绑定DisplayMemberPath指定的属性路径
    3. 使用ItemsControl的ItemContainerStyle设置了ItemContainer的Style

关于这个方法需要说明的几点是:

      1. ItemTemplate和DisplayMemberPath不能同时设置,否则会抛出异常
      2. 如果自定义的ItemsControl在显示Item时出现问题的话,就检查是否正确的重写了该方法,比如是否覆盖了base的实现,而且还没有正确设置ItemTemplate、ItemContainer这些属性
  • ClearContainerForItemOverride,这个方法在ItemsControl中Item被从界面显式中移除时执行,用来清理ItemContainer使用的资源,可以在这里解注册ItemContainer注册的事件等操作

未完待续…………………

最新文章

  1. JS技巧
  2. PSP记录个人项目耗时情况
  3. startssl 申请证书,并在Nginx, apache, Tomcat上使用
  4. jQuery旋转插件jqueryrotate 图片旋转
  5. zipkin分布式链路追踪系统
  6. 【UVA】580-Critical Mass
  7. CSS3的属性为什么要带前缀
  8. YIi2 Pjax简单使用
  9. 漫谈PHP代码规范
  10. iOS中UIWebView执行JS代码(UIWebView)
  11. 仿vue实现简易版mvvm双向绑定
  12. Odoo 12 开发手册指南(八)—— 业务逻辑 – 业务流程的支持
  13. Windows系统服务管理
  14. hdoj4871
  15. Node.js随手笔记
  16. 定时释放Linux/CentOS缓存
  17. centos设置中文输入法无效的解决办法
  18. 《LINUX内核设计与实现》第五章学习总结
  19. javaweb笔记五
  20. 编写shell脚本一键启动zookeeper集群!!

热门文章

  1. win10下安装docker步骤(一)
  2. 一个封装了的选项卡效果js
  3. Android音频输入通道的底层硬件和软件开发分析
  4. C# 使用外部别名
  5. R 语言基本操作(基本信息的查看、与本地文件系统交互、编译器版本升级)
  6. android中滑动SQLite数据库分页加载
  7. 用java写的后台方法可以提供给C#调用吗?(转)
  8. 【oracle11g,13】表空间管理2:undo表空间管理(调优) ,闪回原理
  9. POJ 1328 Radar Installation(经典贪婪)
  10. SICP 锻炼 (1.40)解决摘要