自定义字段类型的开发[转]
?
自定義字段類型的開發(fā)--2級(jí)聯(lián)動(dòng)Combox
在網(wǎng)上找了一些關(guān)于自定義字段類型開發(fā)的文章。發(fā)現(xiàn)在MOSS開發(fā)中關(guān)于這一部分的文章很少。不過這些也夠我們?nèi)腴T了。
1,創(chuàng)建MOSS2007自定義字段類型實(shí)例
2,創(chuàng)建具有屬性值的MOSS2007自定義字段實(shí)例
3,How to: Create a Custom Field Type and Field Control
? ? 前兩篇是賞梅齋的,后一篇是MSDN上的。都是很好實(shí)例,相信看過后都會(huì)有不少的領(lǐng)悟。
? ? 好了,廢話不多說了,下面就開始開發(fā)這個(gè)2級(jí)聯(lián)動(dòng)Combox。
?
? ? 先創(chuàng)建一個(gè)SharePoint空項(xiàng)目,然后再添加一個(gè)新字段控件項(xiàng)目。在建立好了項(xiàng)目后,模板會(huì)自動(dòng)為我們添加一些文件:
1,CityCombox.Field.cs;
2,CityCombox.FieldControl.cs;
3,fldtypes_CityCombox.xml;
? ? 還得自己再添加一下文件:
1,CityComboxValue.cs;
2,CityControl.ascx;
3,CityXMLFile.xml;
? ? 在創(chuàng)建CityControl.ascx文件時(shí),請(qǐng)注意目錄結(jié)構(gòu),這會(huì)省去我們?cè)诓渴饡r(shí)的一點(diǎn)小操作。
? ? 建好了項(xiàng)目,我們就該開始寫代碼了。如果看了前面提到的三篇文章,就會(huì)發(fā)現(xiàn),自定義字段類型的開發(fā),基本上是繼承SharePoint以提供的類型,在源類型上,進(jìn)行成員方法的重寫。
1,類型對(duì)象CityCombox.Field
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Security;
namespace CityCombox
{
// TODO: Replace, as needed, "SPFieldText" with some other class derived from SPField.
// TODO: Update, as needed, ParentType element in fldtypes*.xml in this solution.
[CLSCompliant(false)]
[Guid("48d7dfb3-a1eb-4c96-af40-0a98b98f021d")]
public class CityComboxField : SPFieldMultiColumn
{
public CityComboxField(SPFieldCollection fields, string fieldName)
: base(fields, fieldName)
{
}
public CityComboxField(SPFieldCollection fields, string typeName, string displayName)
: base(fields, typeName, displayName)
{
}
public override BaseFieldControl FieldRenderingControl
{
[SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
get
{
BaseFieldControl fieldControl = new CityComboxFieldControl();
fieldControl.FieldName = this.InternalName;
return fieldControl;
}
}
public override object GetFieldValue(string value)
{
if (string.IsNullOrEmpty(value))
return null;
return new CityComboxValue(value);
}
}
}
?
? ? 注意藍(lán)色部分,這里繼承的是SPFieldMultiColumn。因?yàn)槲覀冏罱K要實(shí)現(xiàn)的效果是在一個(gè)字段里記錄兩個(gè)數(shù)據(jù),所以繼承了SPFieldMultiColumn對(duì)象。
? ? 紅色部分繼承之SPField,綠色部分重寫了SPFieldMultiColumn的成員方法,用于得到我們自定義的控件。
? ? 黃色部分是需要我們自己添加的,前面的代碼都是由模板自動(dòng)生成的。因?yàn)檫@種特殊的開發(fā)方式(重寫),就需要我們對(duì)源對(duì)象有所了解,這樣才知道該重寫什么部分。那么看源碼,也是一個(gè)必須的工作。
? ? 類型部分的代碼就寫完了。而重點(diǎn)在控件部分,我們下面就來看控件部分的代碼。
2,控件對(duì)象CityCombox.FieldControlCODE: using System;
using System.Runtime.InteropServices;
using System.Web.UI.WebControls ;
using System.Xml;
using System.Collections.Generic;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
namespace CityCombox
{
// TODO: Replace, as needed, "TextField" with some other class derived from Microsoft.SharePoint.WebControls.BaseFieldControl.
[CLSCompliant(false)]
[Guid("34e11e08-29f1-4a8e-8ed2-8800c3c1a5dc")]
public class CityComboxFieldControl : BaseFieldControl
{
protected DropDownList ddl_Province, ddl_City;
protected override string DefaultTemplateName
{
get
{
return "CityComboxFieldRendering";
}
}
public override object Value
{
get
{
EnsureChildControls();
CityComboxValue fieldValue = new CityComboxValue();
fieldValue.Province = ddl_Province.SelectedValue.Trim();
fieldValue.City = ddl_City.SelectedValue.Trim();
return fieldValue;
}
set
{
EnsureChildControls();
CityComboxValue fieldValue = (CityComboxValue)value;
ddl_Province.SelectedValue = fieldValue.Province;
ddl_Province_SelectedIndexChanged(null, null);
ddl_City.SelectedValue = fieldValue.City;
}
}
public override void Focus()
{
EnsureChildControls();
ddl_Province.Focus();
}
protected override void CreateChildControls()
{
if (Field == null)
return;
base.CreateChildControls();
if (ControlMode == SPControlMode.Display)
return;
ddl_Province = (DropDownList)TemplateContainer.FindControl("ddl_Province");
if (ddl_Province == null)
throw new ArgumentException("Corrupted CityComboxFieldRendering template - missing ddl_Province. ");
ddl_Province.TabIndex = TabIndex;
ddl_Province.CssClass = CssClass;
ddl_Province.ToolTip = Field.Title + " Province";
ddl_City = (DropDownList)TemplateContainer.FindControl("ddl_City");
if (ddl_City == null)
throw new ArgumentException("corrupted CityComboxFieldRendering template - missing ddl_City.");
ddl_City.TabIndex = TabIndex;
ddl_City.CssClass = CssClass;
ddl_City.ToolTip = Field.Title + " City";
ddl_Province.Enabled = false;
ddl_City.Enabled = false;
if (ControlMode == SPControlMode.New || ControlMode == SPControlMode.Edit)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(Environment.CurrentDirectory +"\\CityXMLFile.xml");
XmlNode rootNode= xmlDoc.SelectSingleNode("Place");
XmlNodeList nodeList = rootNode.ChildNodes;
ddl_Province.Items.Clear();
foreach (XmlNode node in nodeList)
{
ddl_Province.Items.Add(new ListItem(node.Attributes["name"].Value.ToString(), node.Attributes["name"].Value .ToString()));
}
if (!ddl_Province.Enabled)
{
ddl_Province.Enabled = true;
ddl_Province.AutoPostBack = true;
ddl_Province.SelectedIndexChanged += new EventHandler(ddl_Province_SelectedIndexChanged);
//ddl_City.SelectedIndexChanged += new EventHandler(ddl_City_SelectedIndexChanged);
}
if (ddl_Province.Items.Count > 0)
{
//ddl_Province.Items[0].Selected = true;
ddl_Province_SelectedIndexChanged(null, null);
}
}
}
private string LoadXml(string province)
{
string result=string.Empty ;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(Environment.CurrentDirectory + "\\CityXMLFile.xml");
XmlNode rootNode = xmlDoc.SelectSingleNode("Place");
XmlNodeList nodeList = rootNode.ChildNodes;
foreach (XmlNode node in nodeList)
{
if (province == "all")
{
result = result + "@" + node.Attributes["name"].Value .ToString();
}
else if(node.Attributes["name"].Value.ToString()==province)
{
XmlNodeList cityList = node.ChildNodes;
foreach (XmlNode city in cityList)
{
result = result + "@" + city.Attributes["name"].Value .ToString();
}
}
}
return result ;
}
void ddl_Province_SelectedIndexChanged(object sender, EventArgs e)
{
//throw new Exception("The method or operation is not implemented.");
ddl_City.Enabled = true;
string[] cityList = LoadXml(ddl_Province.SelectedValue).Split(new char[1]{'@'},StringSplitOptions.RemoveEmptyEntries);
ddl_City.Items.Clear();
for (int i = 0; i < cityList.Length; i++)
{
ddl_City.Items.Add(new ListItem(cityList[i], cityList[i]));
}
}
}
}
? ? 首先重寫了DefaultTemplateName屬性,該屬性是用來獲取模板的,所以這里返回我們自己的模板。
? ? 接著重寫了Value屬性,類型對(duì)象就通過這個(gè)屬性來獲取控件上的值,或者將值傳給控件。
? ? 最后重寫了CreateChildControls成員方法。在MOSS中需要用到控件時(shí),就會(huì)調(diào)用這個(gè)方法,我們?yōu)榱藢?shí)現(xiàn)特殊的功能,就要重寫這個(gè)方法。
? ? 在這里個(gè)例子里,我們想要實(shí)現(xiàn)的就是,給用戶提供兩個(gè)Combox控件,第一個(gè)Combox控件里是省名數(shù)據(jù),當(dāng)用戶選擇了第一個(gè)Combox控件里的數(shù)據(jù),那么就根據(jù)第一個(gè)Combox控件里的省名來確定第二Combox控件里的城市,提供給用戶選擇。
? ? 在CreateChildControls方法里,一開始先進(jìn)行了一些基本的判斷,然后就從我們的自定義模板里尋找我們需要的兩個(gè)控件(我們這里用的是 DropDownList控件)。接著我們就對(duì)第一Combox進(jìn)行初始化。我們這里的數(shù)據(jù)來至一個(gè)XML文檔CityXMLFile.xml。在對(duì)第一個(gè)Combox控件初始化后,我們就要設(shè)定該控件進(jìn)行自動(dòng)回傳,接著綁定它的SelectedIndexChanged事件到事件處理函數(shù) ddl_Province_SelectedIndexChanged。在ddl_Province_SelectedIndexChanged函數(shù)里,我們要做的就是根據(jù)第一個(gè)Combox控件里選定的數(shù)據(jù),來綁定第二個(gè)Combox。
? ? 控件部分的代碼我們就完成了。在這部份代碼里,我們用到了CityComboxValue這個(gè)對(duì)象。
3,值對(duì)象CityComboxValue
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using System.Web;
namespace CityCombox
{
? ? class CityComboxValue : SPFieldMultiColumnValue
? ? {
? ? ? ? private const int numberOfFields = 2;
? ? ? ? public CityComboxValue() : base(numberOfFields) { }
? ? ? ? public CityComboxValue(string value) : base(value) { }
? ? ? ? public string Province
? ? ? ? {
? ? ? ? ? ? get { return this[0]; }
? ? ? ? ? ? set { this[0] = value; }
? ? ? ? }
? ? ? ? public string City
? ? ? ? {
? ? ? ? ? ? get { return this[1]; }
? ? ? ? ? ? set { this[1] = value; }
? ? ? ? }
? ? }
}
?
? ? CityComboxValue繼承至SPFieldMultiColumnValue。為了在一個(gè)字段內(nèi)保存多個(gè)值,所以我們要定義兩個(gè)屬性。
4,用戶控件CityControl.ascx
<%@ 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="CityComboxFieldRendering" runat="server">
? ? <Template>
? ? ? ? <table>
? ? ? ? ? ? <tr>
? ? ? ? ? ? ? ? <td>Province:</td>
? ? ? ? ? ? ? ? <td><asp:DropDownList ID="ddl_Province" runat="server">
? ? ? ? ? ? ? ? </asp:DropDownList></td>
? ? ? ? ? ? ? ? <td>City:</td>
? ? ? ? ? ? ? ? <td><asp:DropDownList ID="ddl_City" runat="server">
? ? ? ? ? ? ? ? </asp:DropDownList></td>? ? ? ? ? ? ? ?
? ? ? ? ? ? </tr>
? ? ? ? </table>
? ? </Template>
</SharePoint:RenderingTemplate>
?
? ? 就是做一個(gè)包含兩個(gè)DropDownList 控件的用戶控件。最后我們來看類型描述文檔。
5,類型描述文檔fldtypes_CityCombox.xml
<FieldTypes>
? <FieldType>
? ? <Field Name="TypeName">CityComboxField</Field>
? ? <Field Name="TypeDisplayName">CityComboxField</Field>
? ? <Field Name="TypeShortDescription">CityComboxField</Field>
? ? <Field Name="ParentType">MultiColumn</Field>
? ? <Field Name="UserCreatable">TRUE</Field>
? ? <Field Name="FieldTypeClass">48d7dfb3-a1eb-4c96-af40-0a98b98f021d</Field>
? ? <PropertySchema>
? ? ? <Fields>
? ? ? ? <Field Name="DefaultProvince" DisplayName="Default Province:" MaxLength="50" DisplaySize="30" Type="Text">
? ? ? ? ? <Default>四川</Default>
? ? ? ? </Field>
? ? ? ? <Field Name="DefaultCity" DisplayName="Default City:" MaxLength="50" DisplaySize="30" Type="Text">
? ? ? ? ? <Default>綿陽(yáng)</Default>
? ? ? ? </Field>
? ? ? </Fields>
? ? </PropertySchema>
? ? <RenderPattern Name="DisplayPattern">
? ? ? <Switch>
? ? ? ? <Expr>
? ? ? ? ? <Column/>
? ? ? ? </Expr>
? ? ? ? <Case Value="">
? ? ? ? </Case>
? ? ? ? <Default>
? ? ? ? ? <HTML><![CDATA[省:]]></HTML>
? ? ? ? ? <Column SubColumnNumber="0" HTMLEncode="TRUE" />
? ? ? ? ? <HTML><![CDATA[ ---- 城市:]]></HTML>
? ? ? ? ? <Column SubColumnNumber="1" HTMLEncode="TRUE"/>
? ? ? ? </Default>
? ? ? </Switch>
? ? </RenderPattern>
? </FieldType>
</FieldTypes>
?
? ? Field標(biāo)簽是對(duì)字段類型的基礎(chǔ)定義。比如<Field Name="TypeShortDescription">指定了在增加欄時(shí)顯示的名稱;<Field Name="ParentType">MultiColumn</Field>則指定了在展示時(shí)的表現(xiàn)類型。
? ? <RenderPattern Name="DisplayPattern">
部分則確定了在展示時(shí)的樣式。既是定義用戶所看到的樣式。
? ?
6,數(shù)據(jù)文檔CityXMLFile.xml
<Place>
? <Province name="四川">? ?
? ? <City name="綿陽(yáng)">綿陽(yáng)</City>
? ? <City name="廣元">廣元</City>
? ? <City name="德陽(yáng)">德陽(yáng)</City>
? ? <City name="成都">成都</City>
? </Province>
? <Province name="新疆">
? ? <City name="烏魯木齊">烏魯木齊</City>
? ? <City name="阿爾泰">阿爾泰</City>
? ? <City name="哈密">哈密</City>
? ? <City name="石河子">石河子</City>
? </Province>
</Place>
?
? ? 最后我們來看看最終的效果
?
轉(zhuǎn)載于:https://www.cnblogs.com/yigedaizi/archive/2009/05/11/1454032.html
總結(jié)
以上是生活随笔為你收集整理的自定义字段类型的开发[转]的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VCP-310
- 下一篇: 《Java程序员,上班那点事儿》书名的由