MOSS自带字段类型和自定义字段(转)

转自http://blog.163.com/szmax_limin/blog/static/581828612007112425248753/

 

MOSS自帶欄位有很多如單行文本框,多行文本框,日期時間,下拉列表等等,但往往這些欄位不能滿足我們的需要(如MOSS的下拉列表只顯示邦定到當前網站的列表,但我們需要邦定到其它網站的列表),那麼我們該怎麼辦呢?這就需要使用自定欄位來實現了.

 

 SPFieldText  单行文本  这个可能是用的最为广泛的字段类型了,它的输入界面就是一个单行文本框,没有数据验证功能(除了是否为空)。可以设置最大长度(局限在255以内)。
 SPFieldMultiLineText  多行文本

 输入界面是一个textarea,根据设置不同,可以是纯文本或者是带格式文本的(按照html格式保存的)。

对应SPFieldType.Note:

 SPFieldNumber  数字  输入界面是textbox,但是带有数据验证(是否为数字,以及最大/最小值等)。
 SPFieldCurrency  货币  和数字其实差不多,只不过现实的时候会多一个货币符号。
 SPFieldBoolean  是/否  一个CheckBox
 SPFieldDateTime  日期  一个带picker的textbox,可以选择“日期和时间”或“仅日期”
 SPFieldChoice  选项(单选)  可以以dropdownlist或者radio button的形式出现。这个字段有点点特别,虽然它看上去只能存一个值,但其实它是多选类(SPFieldMultiChoice)的子类
 SPFieldMultiChoice  选项(多选)  如果使用多选,那么是通过一组checkbox输入的。在这个类里面定义了这个字段中究竟有哪些选项(通过Choices属性,自然,作为它子类的SPFieldChoice也有这个属性)。于之相对应的,可以通过SPFieldMultiChoiceValue类来访问它的值。
 SPFieldRatingScale  评估范围 刚才介绍过了,它其实也是多选类(SPFieldMultiChoice)的子类。于之对应的值类型为SPFieldRatingScaleValue
 SPFieldUrl  链接或图片  可以是链接,也可以是图片,它包含url和描述信息两个部分,通过其值类型SPFieldUrlValue可以很方便的得到这两部分。
 SPFieldLookup  查阅项  通过dropdownlist完成单选,一个特殊的listbox完成多选(wss3.0支持查阅项多选了!),由于每个被查阅的项会有id和文本,所以也需要有值类型,这个比较特殊,有两种值类型,SPFieldLookupValue和SPFieldLookupValueCollection(因为支持多选了嘛)。然后在SPFieldLookup类中,定义了要查阅哪个列表的哪个字段,以及是哪个网站上的列表。是的!wss3.0中的查阅项其实是支持跨网站查阅的(通过设定LookupWebId属性),但是在默认的界面上并没有暴露出一点。所以一个跨网站查阅项是一个很值得一做的自定义字段类型!
 SPFieldUser  用户和用户组  它的输入是通过一个带有AJAX支持的输入框完成的,这是一个很强大的控件。其实这个类是SPFieldLookup的子类,因为它们做的事情在本质上都差不多。相应的,其值类型SPFieldUserValue也是SPFieldLookupValue的子类,还有SPFieldUserValueCollection……
 SPFieldMultiColumn  多栏  这是另一个很特殊的字段类型,默认情况下我们无法直接使用它,使用它的唯一途径就是通过自定义字段类型继承它来完成我们的需求。顾名思义,这是一个能在一个字段中储存多个信息的字段类型。
     

1. MOSS自定欄位由五個文件組成(開發文件...)

  • SPFieldMultiColumnValue類的實現類:表示自定欄位的值類(自定欄位的值就是這個類的一個實例)
  • BaseFieldControl類的實現類:表示自定欄位的控件類(自定欄位由哪些基本控件組成)
  • SPFieldMultiColumn類的實現類:表示自定欄位類
  • .ascx文件即控件類的模板(我們可以把這個文件看成是一般Web程式中的.ascx文件,而把控件類看成是.ascx.cs文件)
  • fldtypes_???.xml文件:自定欄位的說明文件,放在12\TEMPLATE\XML目錄下

2, 這里我以一個可邦定到其它網站列表中下拉框為例來說明MOSS自定欄位的制作:

(1) SPFieldMultiColumnValue類的實現類

class ListFieldValue : SPFieldMultiColumnValue
{   //自定議字段的值類
    private const int numberOfFields = 1;   //控件個數

    public ListFieldValue() : base(numberOfFields) { }
    public ListFieldValue(string value) : base(value) { }

    public string ListPK
    {   /* 列表標識 */
        get { return this[0]; }
        set { this[0] = value; }
    }

}

(2) BaseFieldControl類的實現類

class ListFieldControl : BaseFieldControl
{   //自定議字段的控件類
    protected DropDownList _ddlist;
    protected override string DefaultTemplateName
    { //指定該控件的模板
        get { return "ListFieldRendering";}
    }

    public override object Value
    { //屬性值(對應的是值類)
        get
        {
            EnsureChildControls();
            ListFieldValue fieldValue = new ListFieldValue();
            fieldValue.ListPK = _ddlist.SelectedValue;
            return fieldValue;
        }
        set
        {
            EnsureChildControls();
            ListFieldValue fieldValue = (ListFieldValue)value;
            _ddlist.SelectedValue = fieldValue.ListPK;
        }
    }

    public override void Focus()
    { //哪個控件取得第一個交點
        EnsureChildControls();
        _ddlist.Focus();
    }

    protected override void CreateChildControls()
    { //創建控件
        if (Field == null) return;
        base.CreateChildControls();
        if (ControlMode == SPControlMode.Display) return;

        _ddlist = (DropDownList)TemplateContainer.FindControl("ddlist");
        if (_ddlist == null) throw new ArgumentException("模板出錯---沒有找到_ddlist的DropDownList控件.");
        _ddlist.TabIndex = TabIndex;
        _ddlist.CssClass = CssClass;
        _ddlist.ToolTip = Field.Title + " ListPK";

        if (ControlMode == SPControlMode.New || ControlMode == SPControlMode.Edit)
        {
            string sitePath = Field.GetCustomProperty("SitePath").ToString();
            string whereList = Field.GetCustomProperty("WhereList").ToString();
            string fieldName = Field.GetCustomProperty("FieldName").ToString();
            BindDDL(sitePath, whereList, fieldName);
        }
    }

    protected SPWeb _web;           //當前站點
    protected void BindDDL(string sitePath, string whereList, string fieldName)
    {   // 將指定網站的列表邦定到這個自定欄位的下位框
        // sitePath格式:/站點名/子站點名/列表名
        if (String.IsNullOrEmpty(sitePath)) return;
        if (String.IsNullOrEmpty(fieldName)) fieldName = "Title";
        string[] tmps = sitePath.Split(new char[] { '/' });

        SPSecurity.RunWithElevatedPrivileges(delegate()
        {
            SPList list;
            using (SPSite site = new SPSite(SPContext.Current.Site.ID))
            {
                if (tmps.Length == 2)
                {   //當前站點
                    _web = SPControl.GetContextWeb(Context);
                }
                else if (tmps.Length > 2)
                {
                    _web = SPControl.GetContextSite(Context).RootWeb;
                    for (int i = 1; i < tmps.Length - 1; i++)
                    {
                        _web = _web.Webs[tmps[i]];
                    }
                }

                if (_web != null)  list = _web.Lists[tmps[tmps.Length - 1]];
                else return;

                SPQuery query = new SPQuery();
                if (!String.IsNullOrEmpty(whereList))
                {
                    query.Query = whereList;
                }
                try
                {
                    SPListItemCollection rows = list.GetItems(query);
                    _ddlist.Items.Clear();
                    foreach (SPListItem row in rows)
                    {
                        try
                        {
                            if (row.Fields[fieldName].TypeDisplayName == "計算")
                            {
                                Regex reg = new Regex(@"[a-z A-Z]{1,10};#");
                                string tmp = reg.Replace(row[fieldName].ToString(), "");
                                _ddlist.Items.Add(tmp);
                            }
                            else
                                _ddlist.Items.Add(row[fieldName].ToString());
                        }
                        catch
                        {
                            _ddlist.Items.Add(row[fieldName].ToString());
                        }
                    }
                }
                catch
                {
                }
            }
        });
    }
}

(3) SPFieldMultiColumn類的實現類

public class ListField : SPFieldMultiColumn
{
    public ListField(SPFieldCollection fields, string fieldName) : base(fields, fieldName) { }
    public ListField(SPFieldCollection fields, string typeName, string displayName) : base(fields, typeName, displayName) { }

    public override BaseFieldControl FieldRenderingControl
    {
        get
        {
            BaseFieldControl fldControl = new ListFieldControl();
            fldControl.FieldName = InternalName;
            return fldControl;
        }
    }

    public override object GetFieldValue(string value)
    {
        if (string.IsNullOrEmpty(value)) return null;
        return new ListFieldValue(value);
    }

}

(4) .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="ListFieldRendering" runat="server">
    <Template>
        <asp:DropDownList ID="ddlist" runat="server">
        </asp:DropDownList>
    </Template>
</SharePoint:RenderingTemplate>

(5) fldtypes_???.xml文件

<?xml version="1.0" encoding="utf-8" ?>
<FieldTypes>

  <FieldType>
    <Field Name="TypeName">CustomListField</Field>
    <Field Name="ParentType">MultiColumn</Field>
    <Field Name="TypeDisplayName">自定欄位</Field>
    <Field Name="TypeShortDescription">自定查閱</Field>
    <Field Name="UserCreatable">TRUE</Field>
    <Field Name="ShowOnListCreate">TRUE</Field>
    <Field Name="ShowOnDocumentLibraryCreate">TRUE</Field>
    <Field Name="ShowOnSurveyCreate">TRUE</Field>
    <Field Name="ShowOnColumnTemplateCreate">TRUE</Field>
    <Field Name="FieldTypeClass">Maxense.Sharepoint.Fields.CustomListField.ListField,Maxense.Sharepoint.Fields, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1a4a2e5dcf17eb82</Field>
    <PropertySchema>
      <Fields>
        <Field Name="SitePath" DisplayName="清單路徑:" DisplaySize="30" Type="Text" Description="範例:/網站/子網站/清單">
          <Default></Default>
        </Field>
        <Field Name="WhereList" DisplayName="查詢條件:" DisplaySize="30" Type="Text" Description="CAML範例:&lt;Where&gt;&lt;Eq&gt;&lt;FieldRef Name='Category'/&gt;&lt;Value Type='Text'&gt;耗材&lt;/Value&gt;&lt;/Eq&gt;&lt;/Where&gt;">
          <Default></Default>
        </Field>
        <Field Name="FieldName" DisplayName="欄位名稱:" DisplaySize="30" Type="Text" Description="被顯示清單的欄位名稱">
          <Default></Default>
        </Field>
      </Fields>
    </PropertySchema>
    <RenderPattern Name="DisplayPattern">
      <Switch>
        <Expr>
          <Column/>
        </Expr>
        <Case Value="">
        </Case>
        <Default>
          <Column SubColumnNumber="0" HTMLEncode="TRUE" />
        </Default>
      </Switch>

    </RenderPattern>
  </FieldType>

</FieldTypes>

上面四個文件也就是跟一般的WEB開發沒什么兩樣,至於fldtypes_???.xml文件我也只知道里面的一些內容,這里就不具體說了,大家可以在網上找了.

到上面為止我們的開發部份算是完成了,接下來的是部署到MOSS上了,這里我采用的方法是做成一個Solution來部署的.當然也可以采用直接拷貝文件的方式來完成;如下:

  1. 將編輯生成的dll文件(注冊要是強簽名文件)放到MOSS服務器中的GAC目錄下.
  2. 將.ascx文件拷貝到12\TEMPLATE\CONTROLTEMPLATES目錄下.
  3. 將fldtypes_???.xml文件拷貝到12\TEMPLATE\XML目錄下.
  4. 重新啟用IIS

這時你在創建欄位時,就可以看到你在fldtypes_???.xml文件中指定的欄位名稱了.

posted @ 2010-09-16 15:19  邑尘  阅读(513)  评论(0编辑  收藏  举报