[SharePoint 2010] 自定义字段类型开发

需求:实现针对单个字段修改权限的控制

实现:从OOB的字段类型中扩展出新的字段类型,能够配置字段的编辑权限。参考资料:

介绍:http://msdn.microsoft.com/zh-cn/library/ms446361(v=office.12).aspx

演练:http://msdn.microsoft.com/zh-cn/library/bb861799(v=office.12).aspx 

1.创建自定义字段类

创建一个类SecureField,继承至SPTextField。重写方法GetValidatedString。在此方法中可进行必填项验证及其他规则验证。

 public class SecureField : SPFieldText
    {
        public SecureField(SPFieldCollection fields, string fieldName)
            : base(fields, fieldName)
        {
        }

        public SecureField(SPFieldCollection fields, string typeName, string displayName)
            : base(fields, typeName, displayName)
        {
        }
      public override string GetValidatedString(object value)
        {
            if ((this.Required == true)
               &&
               ((value == null)
                ||
               ((String)value == "")))
            {
                throw new SPFieldValidationException(this.Title
                    + " must have a value.");
            }

            return base.GetValidatedString(value);
        }
    }

2.创建自定义呈现控件

呈现控件和呈现模板结合可以控制字段在不同模式(新建、编辑、显示)下的呈现。  

创建类SecureFieldControl,继承至Microsoft.SharePoint.WebControls.TextField。由于要能够控制该字段根据当前用户的权限来呈现,需要在此类中重写CreateChildControls。  

 public class SecureFieldControl : TextField
    {
       protected override void CreateChildControls()
        {
            if (this.Field != null)
            {
                base.CreateChildControls();
             }
        }

        public override object Value
        {
            get
            {
                EnsureChildControls();
                return base.Value;
            }
            set
            {
                EnsureChildControls();
                base.Value = (String)value;
            }
        }
    }

3.创建自定义呈现模板

 呈现模板部署后位于:C:\Program Files\Common Files\Microsoft Shared\web server extensions\14(或12)\TEMPLATE\ControlTemplates目录下。配合之前的呈现控件,在CreateChildControls中切换不同的模版进行控件呈现。

在项目中新建用户控件SecureFieldControl.ascx,删除cs和designer.cs文件,修改ascx文件中页面指令Control的属性。添加RenderingTemplate。

我定义了两个RenderingTemplate,其中ID为SecureFieldControl的模板用来在编辑和新建的模式下使用,另一个在显示的模式下使用。

<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls"
    Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Register TagPrefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages"
    Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Control Language="C#" %>
<SharePoint:RenderingTemplate ID="SecureFieldControl" runat="server">
    <Template>
        <asp:TextBox ID="TextField" runat="server" />
    </Template>
</SharePoint:RenderingTemplate>
<SharePoint:RenderingTemplate ID="FieldValueForDisplay" runat="server">
    <Template>
        <asp:Label ID="ValueForDisplay" runat="server" />
    </Template>
</SharePoint:RenderingTemplate>

定义好RenderingTemplate之后,需要修改呈现控件类SecureFieldControl。在类SecureFieldControl中重写DefaultTemplateName和DisplayTemplateName属性。

其中SecureFieldControl和FieldValueForDisplay是已经定义好的RenderingTemplate的ID。

     protected override string DefaultTemplateName
        {
            get
            {
                if (this.ControlMode == SPControlMode.Display)
                {
                    return this.DisplayTemplateName;
                }
                else
                {
                    return "SecureFieldControl";
                }
            }
        }

        public override string DisplayTemplateName
        {
            get
            {
                return "FieldValueForDisplay";
            }
            set
            {
                base.DisplayTemplateName = value;
            }
        }

4.创建自定义类型定义

 现在已经定义好控件类、控件呈现类和控件呈现模版。要实现根据当前用户的权限来切换呈现模板,还需要定义字段属性。我这里需要定义一个属性来保存字段编辑人员。

首先,在项目中添加xml文件作为字段类型的定义文件。注意,该xml文件必须以"fldtypes"开头。我这里的名字是:fldtypes_SecureField.xml

http://msdn.microsoft.com/zh-cn/library/ms415141(v=office.12).aspx

<?xml version="1.0" encoding="utf-8" ?>
<FieldTypes>
    <FieldType>
        <Field Name="TypeName">SecureField</Field>
        <Field Name="ParentType">Text</Field>
        <Field Name="TypeDisplayName">SecureField</Field>
        <Field Name="TypeShortDescription">自定义的安全字段</Field>
        <Field Name="UserCreatable">TRUE</Field>
        <Field Name="ShowOnListCreate">TRUE</Field>
        <Field Name="ShowOnSurveyCreate">TRUE</Field>
        <Field Name="ShowOnDocumentLibraryCreate">TRUE</Field>
        <Field Name="ShowOnColumnTemplateCreate">TRUE</Field>
        <Field Name="FieldTypeClass">SP.EmployeeTran.SecureField, $SharePoint.Project.AssemblyFullName$</Field>
        <PropertySchema>
            <Fields>
                
            </Fields>
        </PropertySchema>
    </FieldType>
</FieldTypes>

设置好Field的各种属性后,接下来在PropertySchema中定义字段属性。

<PropertySchema>
    <Fields>
        <Field Name="SecurityPeoples" DisplayName="字段编辑人员" Type="UserMulti"  Mult="TRUE" UserSelectionMode="PeopleOnly">
        </Field>
    </Fields>
</PropertySchema>

接下来,我们修改控件呈现类SecureFieldControl中的CreateChildControls来完成实现。

我的需求是:网站管理员、组Admin中的成员及属性"SecurityPeoples"中的人员可以编辑字段。

首先,在类SecureFieldControl中定义变量。

 protected Label FieldValueForDisplay;

接着修改CreateChildControls内容。

        protected override void CreateChildControls()
        {
            if (this.Field != null)
            {
                base.CreateChildControls();
                this.textBox = (TextBox)TemplateContainer.FindControl("TextField");
                this.FieldValueForDisplay = (Label)TemplateContainer.FindControl("ValueForDisplay");

                if (this.ControlMode != SPControlMode.Display)
                {
                    if (!this.Page.IsPostBack)
                    {
                        if (this.ControlMode == SPControlMode.New)
                        {
                            textBox.Text = string.Empty;
                        }
                        else
                            textBox.Text = Convert.ToString(Value);
                    }

                    //control edit right
                    if (SPContext.Current.Web.CurrentUser.IsSiteAdmin) return;

                    foreach (SPGroup group in SPContext.Current.Web.CurrentUser.Groups)
                    {
                        if (group.Name == "Admin") return;
                    }
                    
                    Microsoft.SharePoint.SPFieldUserValueCollection spuvc = (Microsoft.SharePoint.SPFieldUserValueCollection)this.Field.GetCustomProperty("SecurityPeoples");
                    if (spuvc == null) return;

                    textBox.Enabled = false;
                    textBox.BackColor = System.Drawing.Color.Silver;
                    string _targ = string.Empty;

                    foreach (Microsoft.SharePoint.SPFieldUserValue spuv in spuvc)
                    {
                        if (spuv.User == null)
                            _targ = spuv.LookupValue;
                        else
                            _targ = spuv.User.LoginName;

                        if (string.Compare(_targ, SPContext.Current.Web.CurrentUser.LoginName, true) == 0)
                        {
                            if (this.ControlMode != SPControlMode.Display)
                            {
                                textBox.Enabled = true;
                                textBox.BackColor = System.Drawing.Color.White;
                            }
                            break;
                        }
                    }
                }
                else
                {
                    FieldValueForDisplay.Text = (String)this.ItemFieldValue;
                }
            }
        }

相关截图:

项目结构

  

创建新栏

 

posted @ 2012-10-10 17:14  一只小小菜鸟  阅读(641)  评论(2编辑  收藏  举报