xinxuaw231 发表于 2015-9-27 11:49:44

Sharepoint SP1下创建自定义字段应注意的问题

  Sharepoint SP1创建自定义字段下面有一个Bug,我不知道SP2解决了这个问题没有:
  通过调用自定义字段类型父类的SetCustomProperty(string propertyName,object propertyValue)来修改属性却不能保存,因此通常的做法是创建一个静态Field来缓存这些设置,利用WSPBuilder来创建的自定义字段在模版中重写SetCustomProperty和GetCustomProperty方法,而不用手工完成,只需调用this.SetCustomProperty或者this.GetCustomProperty就可以了,不能调用base.SetCustomProperty和base.GetCustomProperty方法。
  字段定义文件如下:


代码



1 <?xml version="1.0" encoding="utf-8" ?>
2<FieldTypes>
3   <FieldType>
4         <Field Name="TypeName">RegularField</Field>
5         <Field Name="ParentType">Text</Field>
6         <Field Name="TypeDisplayName">A Regular Field</Field>
7         <Field Name="TypeShortDescription">A field type for regular expression</Field>
8         <Field Name="UserCreatable">TRUE</Field>
9         <Field Name="Sortable">TRUE</Field>
10         <Field Name="AllowBaseTypeRendering">TRUE</Field>
11         <Field Name="Filterable">TRUE</Field>
12         <Field Name="FieldTypeClass">SingTel.SharePoint.CustomFields.RegularField,
        SingTel.SharePoint.CustomFields, Version=1.0.0.0, Culture=neutral,
        PublicKeyToken=fc0c17e3617723dd</Field>
13         <PropertySchema>
14             <Fields>
15               <Field Hidden="FALSE" Name="RegularExpression" DisplayName="Regular Expression" Type="Text" Required="TRUE">
            </Field>
16               <Field Hidden="FALSE" Name="ErrorMessage" DisplayName="Error Message" Type="Text" Required="TRUE">
            </Field>
17             </Fields>
18             <Fields></Fields>
19         </PropertySchema>
20         <RenderPattern Name="DisplayPattern">
21             <HTML><!]></HTML>
22             <Column/>
23             <HTML><!]></HTML>
24         </RenderPattern>
25   </FieldType>
26</FieldTypes>
  
字段类型代码:



代码



1 using System;
2using System.Collections.Generic;
3using System.Text.RegularExpressions;
4using Microsoft.SharePoint;
5using Microsoft.SharePoint.WebControls;
6
7namespace SingTel.SharePoint.CustomFields
8 {
9   public class RegularField : SPFieldText
10   {
11         private static string[] CustomPropertyNames = new string[] { "RegularExpression", "ErrorMessage" };
12         public RegularField(SPFieldCollection fields, string fieldName)
13             : base(fields, fieldName)
14         {
15             InitProperties();
16         }
17         public RegularField(SPFieldCollection fields, string typeName, string displayName)
18             : base(fields, typeName, displayName)
19         {
20             InitProperties();
21         }
22         #region Property storage and bug workarounds - do not edit
23         /// <summary>
24         /// Indicates that the field is being created rather than edited. This is necessary to
25         /// work around some bugs in field creation.
26         /// </summary>
27          public bool IsNew
28         {
29             get { return _IsNew; }
30             set { _IsNew = value; }
31         }
32         private bool _IsNew = false;
33         /// <summary>
34         /// Backing fields for custom properties. Using a dictionary to make it easier to abstract
35         /// details of working around SharePoint bugs.
36         /// </summary>
37          private Dictionary<string, string> CustomProperties = new Dictionary<string, string>();
38         /// <summary>
39         /// Static store to transfer custom properties between instances. This is needed to allow
40         /// correct saving of custom properties when a field is created - the custom property
41         /// implementation is not used by any out of box SharePoint features so is really buggy.
42         /// </summary>
43         private static Dictionary<string, string> CustomPropertiesForNewFields = new Dictionary<string, string>();
44         /// <summary>
45         /// Initialise backing fields from base property store
46         /// </summary>
47         private void InitProperties()
48         {
49             foreach (string propertyName in CustomPropertyNames)
50             {
51               CustomProperties = base.GetCustomProperty(propertyName) + "";
52             }
53         }
54         /// <summary>
55         /// Take properties from either the backing fields or the static store and
56         /// put them in the base property store
57         /// </summary>
58         private void SaveProperties()
59         {
60             foreach (string propertyName in CustomPropertyNames)
61             {
62               base.SetCustomProperty(propertyName, GetCustomProperty(propertyName));
63             }
64         }
65         /// <summary>
66         /// Get an identifier for the field being added/edited that will be unique even if
67         /// another user is editing a property of the same name.
68         /// </summary>
69         /// <param name="propertyName"></param>
70         /// <returns></returns>
71         private string GetCacheKey(string propertyName)
72         {
73             return SPContext.Current.GetHashCode() + "_" + (ParentList == null ? "SITE" : ParentList.ID.ToString()) + "_" + propertyName;
74         }
75         /// <summary>
76         /// Replace the buggy base implementation of SetCustomProperty
77         /// </summary>
78         /// <param name="propertyName"></param>
79         /// <param name="propertyValue"></param>
80         new public void SetCustomProperty(string propertyName, object propertyValue)
81         {
82             if (IsNew)
83             {
84               // field is being added - need to put property in cache
85               CustomPropertiesForNewFields = propertyValue + "";
86             }
87             CustomProperties = propertyValue + "";
88         }
89         /// <summary>
90         /// Replace the buggy base implementation of GetCustomProperty
91         /// </summary>
92         /// <param name="propertyName"></param>
93         /// <param name="propertyValue"></param>
94         new public object GetCustomProperty(string propertyName)
95         {
96             if (!IsNew && CustomPropertiesForNewFields.ContainsKey(GetCacheKey(propertyName)))
97             {
98               string s = CustomPropertiesForNewFields;
99               CustomPropertiesForNewFields.Remove(GetCacheKey(propertyName));
100               CustomProperties = s;
101               return s;
102             }
103             else
104             {
105               return CustomProperties;
106             }
107         }
108         /// <summary>
109         /// Called when a field is created. Without this, update is not called and custom properties
110         /// are not saved.
111         /// </summary>
112         /// <param name="op"></param>
113         public override void OnAdded(SPAddFieldOptions op)
114         {
115             base.OnAdded(op);
116             Update();
117         }
118         #endregion
119         public override BaseFieldControl FieldRenderingControl
120         {
121             get
122             {
123               BaseFieldControl fieldControl = new RegularFieldControl();
124
125               fieldControl.FieldName = InternalName;
126
127               return fieldControl;
128             }
129         }
130         public override void Update()
131         {
132             SaveProperties();
133             base.Update();
134         }
135         public string RegularExpression
136         {
137             get { return this.GetCustomProperty("RegularExpression") + ""; }
138             set { this.SetCustomProperty("RegularExpression", value); }
139         }
140         public String ErrorMessage
141         {
142             get
143             {
144               return this.GetCustomProperty("ErrorMessage") + "";
145             }
146             set
147             {
148               this.SetCustomProperty("ErrorMessage", value);
149             }
150         }
151         public override string GetValidatedString(object value)
152         {
153             if(value==null || String.IsNullOrEmpty(value.ToString())) throw new SPFieldValidationException("Value is null or empty");
154             if(!Regex.IsMatch(value.ToString(),RegularExpression)) throw new SPFieldValidationException(ErrorMessage);
155             return base.GetValidatedString(value);
156         }
157   }
158 }
  UI控件如下:



代码



1 using System.Web.UI;
2 using System.Web.UI.WebControls;
3 using Microsoft.SharePoint.WebControls;
4
5 namespace SingTel.SharePoint.CustomFields
6 {
7   public class RegularFieldControl : BaseFieldControl
8   {
9         private TextBox textBox;
10         public RegularFieldControl() { }
11
12         protected override void CreateChildControls()
13         {
14             base.CreateChildControls();
15             if (this.ControlMode == SPControlMode.Display)
16             {
17               this.Controls.Add(new LiteralControl("" + this.Value));
18             }
19             else
20             {
21               textBox = new TextBox();
22               this.Controls.Add(textBox);
23             }
24         }
25         public override object Value
26         {
27             get
28             {
29               EnsureChildControls();
30               if (this.textBox != null)
31                     return this.textBox.Text;
32               else
33                     return null;
34             }
35             set
36             {
37               EnsureChildControls();
38               if (this.textBox != null)
39               {
40                     this.textBox.Text = "" + value;
41               }
42             }
43         }
44   }
45 }
  补充:上面字段类型代码中有点错误,应该在该字段必须填写的情况下才执行验证,改正如下:



代码



1 public override string GetValidatedString(object value)
2 {
3   if (base.Required)
4   {
5         if (value == null || String.IsNullOrEmpty(value.ToString())) throw new SPFieldValidationException("Value is null or empty");
6         if (!Regex.IsMatch(value.ToString(), RegularExpression)) throw new SPFieldValidationException(ErrorMessage);
7   }
8   return base.GetValidatedString(value);
9 }
  
  
页: [1]
查看完整版本: Sharepoint SP1下创建自定义字段应注意的问题