WPF自定义集合控件概述与遇到的问题

简介: WPF中涉及到控件,那么就不可能绕过Template。首先咱们来看一下WPF中基础集合控件ItemsControl涉及到的几个Template。 ItemsControl自身的Template,类型为ControlTemplate,其内部声明了一个ItemsPresenter用以呈现下述第2个Template。

WPF中涉及到控件,那么就不可能绕过Template。首先咱们来看一下WPF中基础集合控件ItemsControl涉及到的几个Template。

  1. ItemsControl自身的Template,类型为ControlTemplate,其内部声明了一个ItemsPresenter用以呈现下述第2个Template。当我们为集合控件赋予自定义模板时,ItemsPresenter不可丢弃,否则就失去了集合控件的意义;
  2. ItemsPanel,类型为ItemsPanelTemplate,其内容一般为可拥有多个子项的布局控件,如StackPanel、Grid等;
  3. ItemTemplate,类型为DataTemplate,呈现各数据项。

此时有人会问,数据项对应的类型是ControlTemplate的Template跑哪里去了?说的是呀,话说只要是继承自Control的控件都应该有这个Template属性,你看ItemsControl不就有吗。那么与各子项对应的这个属性应该怎么获取和设置呢。ItemsControl并没有提供给我们直接访问子项Template属性的方法,而是给了另一个属性ItemContainerStyle。ItemContainerStyle对应子项控件的Style,因此我们可以通过该Style设置子项控件的Template(上述第3条实际上对应子项控件Template内的ContentPresenter)。ItemContainerStyle对于ItemsControl是设置ContentPresenter的样式,不过ContentPresenter并没有Template属性,但是对于ListBox来说,它设置的是ListBoxItem的Style。

关于为什么wpf不给我们直接设置子项控件Template的方法,我没有特地研究过,不过我想微软的开发人员是这么想的:也许有人希望在保持原先默认的Template,对其它属性做一些掌控,比如可见性,那么何不如直接给你们设置所有样式的机会呢?(上帝说,要有光。于是就有了光。我等P民感恩戴德。)

WPF灵活地样式自定义给了开发人员极大的便利,同时也带来了可能破坏控件内在逻辑的问题。如何做到设计和逻辑分离,周大牛在WPF中自定义控件(3) CustomControl说的很详细,不过由于该博文“年代久远”,因此不排除有过时的内容。

原本我打算自定义一个名为UserAddDelItemsControl的集合控件,该控件继承自ItemsControl,为用户提供自增删子项的功能,但进行到一半的时候发现它的ItemsSource属性给我造成了相当大的麻烦。ItemsSource != null即有数据源绑定时,我要去判断可能的数据源类型,谢天谢地,大部分实体数据源都继承自IList,该接口有我期望的Insert、Remove等方法。但是假设我Insert一个新数据项(注意此处是数据项)的时候,我要不要去刷新界面,以及如何去刷新界面以反映后台数据列表的更改呢,所以我又要去判断数据源是否继承自INotifyCollectionChanged。假如它没有继承自INotifyCollectionChanged,那么我该怎么办?或许我该使用 ICollectionView.Refresh()方法?或许最终可以实现,但这样的控件并不能使我满意。我意识到要实现一个优良的可增删项的集合控件的真正重点和难点是需要重写ItemsSource属性,甚至要为其自定义一套数据源处理逻辑。水太深鸟!时间不多,我只能暂时放弃。

不过该项工作并没有白做,除自定义控件的知识外,重温并加深了关于Command、VisualState(4.0,可以理解为Trigger的升级版)的知识。

  1. RoutedCommand,可理解为事件event,或者更本质上,其实是一个信号。控件(如按钮)触发这个命令,有人(类或实例)收到这个命令,检查自己能否处理(拥有的CommandBindingCollection是否包含与这个命令相关的CommandBinding(检查其Command属性)),若找到对应的CommandBinding,那么就执行CommandBinding的Executed逻辑。
  2. 按第1条理解,RoutedCommand定义在哪里并不要紧,一般将之定义为自定义控件的静态字段。
  3. 事件和命令的区别,个人理解:事件的信号源是一个,关注者收到信号后做自己计划做的事,信号源并不care关注者做什么事;命令的信号源可以有多个,当然关注者也可以有多个,一般来说,所有信号源都期望关注者执行一个或一组逻辑,而关注者也遵循它们的意愿,这里的关注者可以理解为代理。
  4. 相同VisualStateGroup包含的所有VisualState互斥,使用VisualStateManager.GoToState来进行状态跳转。

转载请注明本文出处:http://www.cnblogs.com/newton/archive/2012/12/28/2836672.html

目录
相关文章
|
4月前
|
开发框架 缓存 前端开发
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件
|
4月前
|
C# 开发者 Windows
一款基于Fluent设计风格、现代化的WPF UI控件库
一款基于Fluent设计风格、现代化的WPF UI控件库
105 1
|
4月前
|
C# Windows
WPF中如何使用HandyCotrol控件库
WPF中如何使用HandyCotrol控件库
199 1
|
4月前
|
C# 前端开发 UED
WPF数据验证实战:内置控件与自定义规则,带你玩转前端数据验证,让你的应用程序更上一层楼!
【8月更文挑战第31天】在WPF应用开发中,数据验证是确保输入正确性的关键环节。前端验证能及时发现错误,提升用户体验和程序可靠性。本文对比了几种常用的WPF数据验证方法,并通过示例展示了如何使用内置验证控件(如`TextBox`)及自定义验证规则实现有效验证。内置控件结合`Validation`类可快速实现简单验证;自定义规则则提供了更灵活的复杂逻辑支持。希望本文能帮助开发者更好地进行WPF数据验证。
139 0
|
4月前
|
C# UED 定位技术
WPF控件大全:初学者必读,掌握控件使用技巧,让你的应用程序更上一层楼!
【8月更文挑战第31天】在WPF应用程序开发中,控件是实现用户界面交互的关键元素。WPF提供了丰富的控件库,包括基础控件(如`Button`、`TextBox`)、布局控件(如`StackPanel`、`Grid`)、数据绑定控件(如`ListBox`、`DataGrid`)等。本文将介绍这些控件的基本分类及使用技巧,并通过示例代码展示如何在项目中应用。合理选择控件并利用布局控件和数据绑定功能,可以提升用户体验和程序性能。
77 0
|
4月前
|
开发框架 前端开发 JavaScript
WPF应用开发之控件动态内容展示
WPF应用开发之控件动态内容展示
|
4月前
|
C#
WPF 自定义可拖动标题栏
WPF 自定义可拖动标题栏
54 0
|
4月前
|
前端开发 C#
wpfui:一个开源免费具有现代化设计趋势的WPF控件库
wpfui:一个开源免费具有现代化设计趋势的WPF控件库
152 0
|
4月前
|
开发框架 前端开发 C#
使用WPF开发自定义用户控件,以及实现相关自定义事件的处理
使用WPF开发自定义用户控件,以及实现相关自定义事件的处理
|
4月前
|
开发框架 前端开发 JavaScript
在WPF应用中使用GongSolutions.WPF.DragDrop实现列表集合控件的拖动处理
在WPF应用中使用GongSolutions.WPF.DragDrop实现列表集合控件的拖动处理