赏梅斋

关注微软技术

博客园 首页 新随笔 联系 订阅 管理


MOSS2007的自定义字段类型是一个非常有用的功能,但在网上相关的实例介绍很少,所以下面就
一步一步地介绍怎样来创建一个自定义字段类型,我们的目标是:实现一个具有可配置性的下拉列表框,
其选择项目是读取XML文件获得。

实现一个自定义字段类型主要需要完成三种文件的编制:1)定义类型的XML文件;2)定义展现模板
*.ascx文件;3)定义后台代码程序集。

这里因为我们想要实现一个可读取XML文件的下拉列表框,所以我们首先还要定义一个配置文件
SelectItemFromXMLConfig.xml。
XML代码如下:

<?xml version="1.0" encoding="utf-8"?>
<SelectItems>
  
<Item>选项一</Item>
  
<Item>选项二</Item>
  
<Item>选项三</Item>
  
<Item>选项四</Item>
  
<Item>选项五</Item>
</SelectItems>

然后,我们可以打开Visual Studio2005,然后添加一个类库,如果你已经安装了扩展模板也可以直接选择
创建“Field Control”类型的项目。建议下载微软的SharePoint工具包:Windows SharePoint Services 3.0 Tools: Visual Studio 2005 Extensions.

这里我们新建一个名叫SelectItemFromXMLField的类库,其中包含两个类文件:SelectItemFromXML.Field.cs
和SelectItemFromXML.FieldControl.cs。

SelectItemFromXML.Field.cs完整代码如下:

using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Security;

namespace SelectItemFromXML
{
    [CLSCompliant(
false)]
    [Guid(
"92f76873-537c-4c13-abaf-2d47bdc7e2be")]
    
public class SelectItemFromXMLField : SPFieldChoice
    
{
        
public SelectItemFromXMLField(SPFieldCollection fields, string fieldName)
            : 
base(fields, fieldName)
        
{
        }

        
        
public SelectItemFromXMLField(SPFieldCollection fields, string typeName, string displayName)
            : 
base(fields, typeName, displayName)
        
{
        }


        
public override BaseFieldControl FieldRenderingControl
        
{
            [SharePointPermission(SecurityAction.LinkDemand, ObjectModel 
= true)]
            
get
            
{
                BaseFieldControl fieldControl 
= new SelectItemFromXMLFieldControl();
                fieldControl.FieldName 
= this.InternalName;

                
return fieldControl;
            }

        }

    }

}

SelectItemFromXML.FieldControl.cs完整代码如下:

using System;
using System.Runtime.InteropServices;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Web.UI.WebControls;
using System.IO;
using System.Xml;
using System.Diagnostics;

namespace SelectItemFromXML
{
    [CLSCompliant(
false)]
    [Guid(
"eb269bd9-0d3e-4aa2-b88f-37fbccb0d7d8")]
    
public class SelectItemFromXMLFieldControl : BaseFieldControl
    
{
        
protected DropDownList cboList;
        
protected override string DefaultTemplateName
        
{
            
get
            
{
                
return "SelectItemFromXMLFieldControl";
            }

        }


        
public override object Value
        
{
            
get
            
{
                EnsureChildControls();
                
return cboList.SelectedValue.ToString();
            }

            
set
            
{
                EnsureChildControls();
                cboList.SelectedValue 
= (string)this.ItemFieldValue;
            }

        }


        
public override void Focus()
        
{
            EnsureChildControls();
            cboList.Focus();
        }


        
protected override void CreateChildControls()
        
{
            
if (Field == nullreturn;
            
base.CreateChildControls();

            
if (ControlMode == Microsoft.SharePoint.WebControls.SPControlMode.Display)
                
return;

            cboList 
= (DropDownList)TemplateContainer.FindControl("cboList");

            
if (cboList == null)
            
{
                
throw new ArgumentException("cboList is null. Corrupted SelectItemFromXMLFieldControl.ascx file.");
            }


            
if (!Page.IsPostBack)
            
{
                    
                    
string configFile = Environment.CurrentDirectory + "\\SelectItemFromXMLConfig.xml";
                    
if (!File.Exists(configFile))
                    
{
                        cboList.Items.Add(
new ListItem("Config file not found!","Error"));
                        cboList.ToolTip 
= configFile + " not found!";
                    }

                    
else
                    
{

                        XmlDocument xmlDoc 
= new XmlDocument();
                        xmlDoc.Load(configFile);

                        XmlNodeList nodelist 
= xmlDoc.DocumentElement.ChildNodes;
                        
foreach (XmlNode node in nodelist)
                        
{
                            cboList.Items.Add(
new ListItem(node.InnerText, node.InnerText));
                        }

                    }

         
            }

            
        }


    }

}

如果你使用模板创建项目,则上面的代码大部分会被自动生成。

值得注意的几个地方是:
 1)SelectItemFromXMLField类将继承SPFieldChoice基类,并重写FieldRenderingControl方法。
 2)SelectItemFromXMLFieldControl 类将继承BaseFieldControl基类。
 3)CreateChildControls方法中读取XML配置文件,并把选项绑定到下拉列表框(DropDownList)子控件上。
 4)上面代码中使用了Environment.CurrentDirectory语句,后面部署时要把配置文件放到

代码编写完成之后,要对程序集进行强名称设置,并编译。

接下来,我们来制作展现模板。你可以在当前解决方案中添加一个文本文件“SelectItemFromXMLFieldControl.ascx”。
然后打该文件编写代码如下:

<%@ Control Language="C#" Debug="true"%>
<%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="SharePoint" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" Namespace="Microsoft.SharePoint.WebControls"  %>

<SharePoint:RenderingTemplate ID="SelectItemFromXMLFieldControl" runat="server">
    
<Template>
        
<asp:DropDownList runat="server" ID="cboList"/>
    
</Template>
</SharePoint:RenderingTemplate>

值得注意的地方是:上面代码中DropDownList的ID是"cboList",这个名字曾经被后台类SelectItemFromXMLFieldControl使用
TemplateContainer.FindControl方法寻找过,所以不要写错。

OK,最后,我们可以在当前解决方案中添加一个XML文件“FLDTYPES_SelectItemFromXmlField.xml”。
代码如下:

<?xml version="1.0" encoding="utf-8"?>
<FieldTypes>
  
<FieldType>
    
<Field Name="TypeName">SelectItemFromXML</Field>
    
<Field Name="ParentType">Choice</Field>
    
<Field Name="TypeDisplayName">Select Item From XML</Field>
    
<Field Name="TypeShortDescription">Select Item From XML</Field>
    
<Field Name="UserCreatable">TRUE</Field>
    
<Field Name="ShowInListCreate">TRUE</Field>
    
<Field Name="ShowInSurveyCreate">TRUE</Field>
    
<Field Name="ShowInDocumentLibraryCreate">TRUE</Field>
    
<Field Name="ShowInColumnTemplateCreate">TRUE</Field>
    
<Field Name="FieldTypeClass">SelectItemFromXML.SelectItemFromXMLField,SelectItemFromXMLField, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ad167643f06d0c9c</Field>
  
</FieldType>
</FieldTypes>

值得注意的地方是:
  1)该定义文件的文件名一定要以“FLDTYPES”开头。
  2)FieldTypeClass项中的值是类的全名称和程序集的全名称,可以使用Reflector获得。


到这里,我们需要编写的所有文件都已经编写完成了,只要做简单的部署就可以了。

步骤如下:

  1)把强名称编译好的SelectItemFromXMLField程序集加入到GAC。
  2)把类型定义文件FLDTYPES_SelectItemFromXmlField.xml拷贝到c:\program...\12\TEMPLATE\XML目录下。
  3)把模板文件SelectItemFromXMLFieldControl.ascx拷贝到c:\program...\12\TEMPLATE\CONTROLTEMPLATES目录下。
    4)重启动IIS。(可以使用命令行iisreset)
  5)把该控件的配置文件SelectItemFromXMLConfig.xml拷贝到C:\Windows\System32\inetsrv目录下。
  
 
值得注意的地方是:
  前四步是部署自定义字段类型的一般步骤。第五步是针对这个实例的特殊步骤。你其实可以把配置文件放在你想放的任何位置,只要在前面编写SelectItemFromXMLFieldControl类的CreateChildControls方法时指定你想放的位置即可。

OK,到此自定义字段类型的过程已经结束。你可以在创建MOSS的某个列表栏时,发现一个新的类型“Select Item From XML”。选择该类型创建一个新栏后,当往该列表中添加项目时,会发现添加页面中对应新栏的输入方式是一个下拉列表框,其中的选项就是我们在XML配置文件中定义的选项了!

posted on 2007-03-15 12:20  赏梅斋  阅读(8248)  评论(25编辑  收藏  举报