WPF ItemsControl深度解读之Items和ItemsSource

    相信不少WPF开发者对控件有一些了解,摆脱了早期微软的MFC,发现WPF编程方式更加方便。但是仍然是浩如烟海般的资料需要了解。控件是WPF开发绕不开的话题。今天我们就从分析ItemsControl控件开始。

    ItemsControl可以包含多个项,神奇的就在于它可以包含字符串或完全用户自己定义的类对象,甚至可以包含Button按钮、StackPanel控件,它是ListBox,ListView,TreeView等其他控件的父类,然而ItemsControl也可以直接作为WPF的控件使用。

首先我们看一下Items和ItemsSource两个属性在ItemsControl中的的定义:



1)下面讲解一个例子,通过ItemsControl的Items属性添加项:


效果如下:


这种用法是在XMAL文件中直接添加<ItemsControl.Items>来达到添加项的目的。但是这种方式貌似只能够添加一项。

2)下面讲解第二个例子,如何通过ItemsControl的Items属性添加多个项,需要通过代码来达到,如下为XMAL文件的代码:



相应的对此ItemsControl添加项的源码如下:


结果如下:


可见ItemsControl的项中可以添加任何对象,可以是字符串,也可以是Button等。

3)根据微软官方的说明文档,指定ItemsSource属性的源,也就是向ItemsSource属性赋一个IEnumerable类型的对象,也可以实现项的添加。需要注意的是当您对ItemsSource设置了属性值之后,则Items属性将变成只读,且Items大小也变为一个固定大小,这就意味着不能通过Items属性添加项了。当ItemsSource属性之前已经设置了一个IEnumerable类型对象,后面又通过代码将ItemsSource设置为null,将删除整个集合项并且Items属性将恢复使用,只不过此时Items是一个空的ItemCollection对象。

例子,XMAL中设置ItemsSource为{Binding Path=strlist}

源文件中定义一个公开的strlist对象(属于List<string>类,也可以是其他IEnumerable类):


效果如下:


现在,我们做个实验,如下使用ItemsControl控件的Items属性再添加一个项:


此时,运行之后会出现如下异常:


==================此处为分割线,熟悉绑定的兄弟姐妹可以不用再往下看=========================

讲到这里,稍微讲一下题外话——绑定,ItemsControl控件的ItemsSource绑定的时候使用如下的绑定扩展表达式:

ItemsSource="{Binding path=strlist}"

这是Binding的一种用法,该写法完全等价于

ItemsSource="{Binding strlist}"

Binding扩展语法表达式第一个属性默认是Path,这个属性可以省略。关于Path的官方解释如下:


上面的意思是赋值给Path的必须是一个属性,假如上面的例子里strlist定义成如下普通成员:

public List<string> strlist;

也就是如果去掉了set,get(通过实验,实际上是需要有get)那么,那么Path方式绑定无效。

另外就是WPF内部有一套绑定引擎在运转,它可以自动通过给Path赋值的字符串获得某个对象的属性,这些过程是自动完成的。

再举个例子,假设有另外一个类叫MyData包含了一个List<string>属性的对象strlist:


这个时候只要将XMAL改为如下即可:


效果一样:


上例中mydata是属性(Property),strlist也是属性(Property),因此Binding写为ItemsSource={Binding mdata.strlist}。

写到这,另外需要指出的是虽然赋值Path必须是属性才可以,貌似绑定源必须是属性。然而,事实并非如此,实际上绑定源并不一定必须是属性,如下例子(该例子来自官网):


这个例子告诉我们可以通过Source属性来绑定一个源,此时绑定源并没有特殊要求,可以不是属性(Property)。因此结论是:

如果是通过Path来指定绑定源,那么后面必须跟着的是一个属性对象;

如果是通过Source指定绑定源,则可以不是属性,可以是任何对象。

猜你喜欢

转载自blog.csdn.net/qq_16587307/article/details/79462137