摘要:从这次开始,将逐步介绍如何创建一个自定义字段类型,以及通过什么样的手段来完成我们需要的功能。 随着例子从简单到复杂,所涉及的内容也有所增长,所以大致的计划流程是这样的:字段类型、xml描述文件、输入控件、值类型、自定义属性控件、自定义属性bug的解决方案、(自定义字段间的通信),大概先分为这几期吧(看来是一个任重而道远的工程……) 那么本期先通过一个最简单的自定义字段类型的例子,来看一下如何创建自定义字段类型中的字段类。 在这个例子中,我们将编写一个Email地址的字段,它可以完成Email地址的合法性验证。 首先,自定义字段类型在SharePoint Extension for Visual Studio 2005里其实是有模板的,但是我们在创建一个项目的时候却看不到它,其实它的创建流程是这样的: 先创建一个空的SharePoint解决方案: 然后在新建一个Item的时候,在可选的模板中就能够看到一个“Field Control”了,选择它: 点确定之后,我们会发现模板为我们创建出了两个文件,xxx.Field.cs和xxx.FieldControl.cs,这两个文件分别定义了字段的类和字段的输入控件。并且自动生成了一个强命名的key,使得我们可以把编译得到的dll放到GAC中。这次主要对字段类进行介绍。 在上上次中介绍过SharePoint的内置的字段类型,每一个字段类型都有自己的类(例如单行文本对应SPFieldText),这些类全部都是SPField的子类。所以,当我们编写一个自己的字段类型的时候,也需要让这个字段类型是SPField的子类,这样才能够完成字段类型的功能。但实际上,我们往往并不需要直接继承SPField,而是找一个与我们所需要的功能最接近的字段类型继承它,这样的优点就是我们可以使用这种内置字段类型的一些特殊属性(比如单行文本中的最长字符数限制等),并且能够使用内置字段类型的默认输入界面,另一个优点就是如果要直接继承SPField,要多写一个东西(但是我忘了是什么了……汗……)。 在这个例子中,Email地址的输入和单行文本非常类似,于是我们继承SPFieldText。 好,可能有人会发现了,默认由模板创建出来的这个项目中它就是继承了SPFieldText的,在我们继续之前,不妨先来看一看这默认生成的代码中都有什么东西。 我们已经看到默认的模板创建出来了Field类和FieldControl类,并且Field类继承了SPFieldText,也就是单行文本。然后在这个Field类中,我们还可以看到如下两大部分内容: 第一部分:构造函数public EmailFieldField(SPFieldCollection fields, string fieldName)
: base(fields, fieldName)
{
}
public EmailFieldField(SPFieldCollection fields, string typeName, string displayName)
: base(fields, typeName, displayName)
{
}
SPFieldText并不支持不带参数的默认构造函数,所以要重载这两种构造函数,而这两种构造函数也是SPField所使用的,默认情况下直接使用相同的参数调用父类的构造函数。通过Reflector我们可以看到,在SPField的这两种构造函数中都是根据参数设置了一些初始值。因此,如果需要有一些特殊的初始值要设置,我们可以放在这个构造函数中,例如如果我们希望这个Email地址栏只在新建界面中出现,而不让用户在默认界面上修改它,我们可以在构造函数中添加:this.ShowInEditForm = false;
我们对这两个构造函数的修改一般也仅限于此类操作了。(其实我们几乎很少需要手动去调用Field系列的构造函数,在创建一个字段时我们往往使用的是SPFieldCollection的Add方法或者AddLookup方法)
在一个自定义的字段类型中,这个构造函数是字段类唯一一个必须重载的地方,其他内容都可以不写(当然如果你其他内容都不写的话,这个字段比起它的父类来说,无非就是多了一些初始值——当你需要这么做的时候,你就可以很简单地这么干来创建一种新的字段类型。。。)
第二部分:关联的控件
在默认生成的代码中,重载了SPFieldText的一个属性叫做FieldRenderingControl。顾名思义,这个只读属性是用来返回与此字段相关联的显示/输入控件的。这部分内容我们放在下下次的内容做介绍。
在这个Email地址的例子中,我们可以直接使用SPFieldText字段类型的默认输入控件(至于显示我们可以放到xml里来定义),因此我们无需重载它,把它删掉好了(同时也可以把那个xxxx.FieldControl.cs也删掉,而且它其实就是空的……)
既然是自定义字段类型,那么必然和默认的单行文本要有所区别,在这个例子中,我们所提供的额外功能就是Email地址的验证,于是我们就需要:
第三部分:数据验证
数据验证功能一般来说都是放在输入界面里做的,但是其实我们也可以把类似的功能放到字段类中(因为我们使用的是默认输入界面)。
在SPField中,有这样一个方法我们可以重载:public override string GetValidatedString(object value)
这个方法的目的就是根据这个字段的值(object),返回一个通过验证的字符串。其主要目的第一在于验证数据,第二在于做数据串行化(Serialization),把数据值都转换成字符串。这个方法在每次提交值的时候都会执行到,所以可以用来进行数据验证。
在重载这个方法的时候,一般我们都先需要判断一下数据是否为空,然后再做真正的自定义的数据校验。如果在校验过程中发现了不合法的数据,我们需要使用一个特殊的Exception类:SPFieldValidationException。这个异常的表现形式就是我们在填错什么东西时,字段输入控件下面会出现的那行红字。
在这个例子中,我们使用正则表达式来验证Email地址,整个函数的函数体如下:public override string GetValidatedString(object value)
{
if (Required && (value == null || value.ToString() == ""))
throw new SPFieldValidationException(SPResource.GetString(Strings.MissingRequiredField));
// Validate email format
string emailRE = @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
if (!Regex.IsMatch(value.ToString(), emailRE))
......[
阅读全文]