自定义列表字段类型(1)
从这一节开始正式涉及到自定义字段类型的内容,嗯……不过这次还是没有代码
本次主要介绍一下自定义列表字段类型的大致内容,用途和缺点,以及大概的体系
上一次说到了SharePoint本身内置了很多种字段类型(其实还有更多,只不过我们没办法自己用罢了,都是系统默认的,比如Counter、File之类),这些字段类型虽然已经比2003时代要丰富而且功能强大了很多,但是有时依然不能满足我们的需求。例如如果你想做一个Email地址栏,你当然可以选择使用单行文本,但是一个好的Email地址输入是可以进行合法性验证的,单行文本却不行;又比如你想做更强大的输入界面,比如评分(现在SharePoint中已经有一个类似的东西了,RatingScale,但是遗憾地它只能用在调查列表中),你希望能把它做成youtube那样的效果;再比如你要做一个能够带有自动判重功能的输入栏……
自定义字段类型是一个很能激发我们想像力的东西,比如我们可以把一个字段类型当做一个按钮,它本身可以不存任何数据,只是在输入界面中根据其它字段来判断一些东西(比如我有两个时间类型的字段分别存放会议开始时间和结束时间,然后我可以做这么一个“按钮”字段,以便在输入的时候就可以判断有没有与此冲突的会议时间——这往往比使用Event Handler更加人性化一些,因为那是在提交后才判断的)。最近越来越发现自定义字段的强大,甚至有一种机制可以让不同字段之间进行交互,今天侯同学刚发现的这一点,大概试了试原理,还没用到字段类型上,等试出来了再说。
好了,言归正传,自定义字段类型主要解决的是以下问题:
- 更复杂的输入、显示界面
- 自定义的合法性判断检测
- 更复杂的逻辑
- 其他一些默认字段所无法完成的功能
举一些例子:
- 地址。我们在网上购物的过程中填写地址时,经常会发现它分成了几个不同的部分让我们输入,比如省、市、区、街道、邮编等等。那么如果使用SharePoint默认功能的话,我们只能把这些分别存在一些栏中,这显然不好。自定义列表字段就可以把它们存在一个栏中,但是可以分别输入各个部分。(事实上,Todd的USAddress这个字段类型也是我见过的第一个自定义字段类型)
- Email地址。如上所述,可以使用正则表达式加上一些合法性验证。
- 评分。更加人性化的输入和输出,让用户使用时不在是只和枯燥的数字打交道。
- 外部数据查阅。虽然默认有了BDC查阅和查阅项,但是有时我们可能会需要更灵活些的查阅,比如跨网站查阅列表内容(还记得么?这是2007支持的功能!但是并没有体现在默认界面上罢了)
当然,自定义字段类型并不是万能的,它有着这样那样的局限,而且其中很多都非常诡异:
- 首先,自定义列表字段是不被office系列的客户端支持的。也就是说,我们觉得很好用的那个“文档信息面板”是不支持自定义字段类型的。我们在文档库中添加一个自定义列表字段时,甚至都会出现这样的提示:
如果你不记得什么是“文档信息面板”的话,喏(在线创建一篇文档时):
- 其次,非常奇怪的,自定义字段类型中的值不能超过255个字符(即使你继承了多行文本也不行!),就“好像”它们都是从单行文本衍生出来似的(我们知道单行文本的最大长度就是255)。这是一个老外发现的,非常没道理的一个限制,那个老外最后用的方法是继承了多选这种字段类型,这样就可以多放几个255字符了,虽然选项数也是有限制的……
- 另外,现在的自定义字段类型有一个很严重的bug,就是按照标准的编程方法(我指的是SDK里写的方法),它无法保存自定义的属性(每个字段类型都有些独特的属性,比如数值型中的最大值、最小值)。当然,这并不意味着我们就不能保存自定义属性,有一些解决方案去使用它(其中一种阳春白雪,从SharePoint存储自定义属性的原理入手,但是这个改起来超级麻烦;另外一种是我发明的,虽然看起来很丑陋,但事实证明有效且简单),我在后面会讲到具体怎么做。
- 最后,我们开发人员最关注的就是,这个东西开发起来比较繁琐,尤其当你有很多需求要加进去时。虽然它并没有workflow那么深奥,但由于涉及到的东西比较多,所以还是有点难度的。还是Web部件和Event Handler容易啊……感叹一下。每次我讲自定义列表字段开发的时候,虽然我已经尽量把它涉及到的原理讲清楚了,但台下的反响还是云里雾里……不自己亲自做几个的话,恐怕是很难深入理解的。
一个自定义的字段类型如果算全了的话,可以分为5个部分(看,我说很繁琐吧……)
- 字段类。一个自定义的字段类型是继承自某个内置的字段类型的(这也是为什么我上次花了这么大功夫把内置的字段类型都罗列了一遍的原因),当然,我们也可以直接继承最基础的字段类型——SPField,但是这样要多做些事情(很遗憾,具体加什么我忘了-.-)。还是建议继承某种已有的吧(比如SPFieldText、SPFieldLookup、SPFieldMultiColumn之类的),大不了我们完全不用它默认的输入输出界面罢了。
- 字段值类。这是一个可选的部分。就像我上一次说的,如果字段的设计比较复杂的话,可能会需要字段值的类型,这种一般都用于一个字段中存储超过一个数据的情况(比如查阅项包含被查阅条目的ID和一个文本,Url包含地址和描述)。如果我们自己的字段类型需要有类似需求的话,可以继承一个已有的值类型,来写一个新的值类型。当然,如果原有的值类型能够满足我们的需求,直接用它就好了。
- 字段输入/显示控件。这也是一个可选的部分,但大多数情况下可能都要写,因为我们往往需要自定义输入的样式和输出的样式。这个控件可以使用一个User Control来做,因此支持可视化设计(如果愿意生写也可以……)
- 自定义属性的输入控件。同样是一个可选部分。自定义的属性对于一个自定义字段类型来说往往还是比较重要的,正是它体现了同一种字段类型下,一个字段和另一个字段的不同之处(比如查阅项查阅不同的列表)。本来这些自定义属性的输入是可以自动生成的,但由于刚刚说的那个bug,我们一般还是需要手动地去写一个自定义属性的输入控件,而且我们可以在这里也加入自定义的一些逻辑。这部分内容同样可以使用User Control,只不过需要再实现一个特殊的接口就行了。
- 字段定义文件。这是一个xml文件,每个自定义的字段类型都必须有(其实默认的那些字段类型也有),而且这个文件名必须以fldtypes_开头。这个文件中定义了关于该字段类型的一些基本信息(比如标题、类型、是否允许用户创建等等),还有它使用到的程序集信息、自定义属性的输入控件信息,另外还有各种显示样式(没错,这里也可以定义显示样式,而且支持一些诸如if、switch之类的条件判断,通过CAML格式实现),以及自定义属性(标准做法中的自定义属性在这里定义)。如果写这个文件时遇到了困难,我们可以参考一下默认的那些字段类型是怎么被定义的,此文件是那个很深的12目录中的"TEMPLATE\XML\FLDTYPES.XML"。
从另一个角度来说,自定义的字段类型也可以分成3个部分:程序集(dll)、控件(ascx)、描述文件(xml)。不妨先在此简要地介绍一下自定义字段类型的部署,很容易:把程序集扔进GAC里,把ascx放到"12\TEMPLATE\CONTROLTEMPLATES",把xml放到"12\TEMPLATE\XML",然后重启iis(一定要重启iis,仅回收应用程序池是不行的),然后就可以再创建栏那里看到新的字段类型了(如果我们没写错什么东西的话……)
从下一次开始,就是主要介绍以上那5个部分的写法,从中一一地展开介绍一下字段类型的工作机理。如果我能试出来字段类型之间通讯的话,我也会做一个介绍。
摘自:http://blog.joycode.com/erucy/archive/2007/11/25/111936.aspx