WSS自定义字段问题:在 RenderPattern 中使用自定义属性

字段配置文件如下:

<FieldTypes>
    
<FieldType>
        
<Field Name="TypeName">WordExport</Field>
        
<Field Name="ParentType">Text</Field>
        
<Field Name="TypeDisplayName">WordExport</Field>
        
<Field Name="TypeShortDescription">WordExport</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="FieldEditorUserControl"></Field>
        
<Field Name="Sortable">FALSE</Field>
        
<Field Name="Filterable">FALSE</Field>
        
<Field Name="FieldTypeClass">MCS.SharePoint.WordExport.WordExportField,MCS.SharePoint, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9a525f21aa237e5b</Field>
        
<PropertySchema>
            
<Fields>
                
<Field Name="ExportTemplate"  DisplayName="ExportTemplate" MaxLength="300" DisplaySize="30" Type="Text" Hidden="FALSE" >
                
</Field>

            
</Fields>
        
</PropertySchema>

        
<RenderPattern Name="DisplayPattern">
            
<HTML><![CDATA[<a href="/_layouts/mcs/wordexport.aspx?itemUrl=]]></HTML>
            
<Field Name="ServerUrl"/>
            
<HTML><![CDATA[&template=]]></HTML>
            
<Property Select="ExportTemplate"/>
            
<HTML><![CDATA[" target="_blank">]]></HTML>
            
<HTML><![CDATA[<img border="0" alt="]]></HTML>
            
<HTML>打印</HTML>
            
<HTML><![CDATA[" src="/_layouts/images/edititem.gif">]]></HTML>
            
<HTML><![CDATA[</a>]]></HTML>
        
</RenderPattern>
        
<!--RenderPattern Name="HeaderPattern">
    <RenderPattern Name="DisplayPattern">
        
        <RenderPattern Name="PreviewDisplayPattern"></RenderPattern>
        <RenderPattern Name="PreviewEditPattern"><Property Select="DisplayName" HTMLEncode="TRUE"/></RenderPattern>
        <RenderPattern Name="PreviewNewPattern"><Property Select="DisplayName" HTMLEncode="TRUE"/></RenderPattern
-->

    
</FieldType>

</FieldTypes>

PropertySchema中声明了一个自定义属性:ExportTemplate,但是这个属性无法在RenderPattern中引用,如上面配置文件的写法,
<Property Select="ExportTemplate"/>输出始终为空。
反射系统的SPFileText的实现,它声明了类似的 MaxLength等属性:


public int MaxLength
{
    
get
    
{
        
string fieldAttributeValue = base.GetFieldAttributeValue("MaxLength");
        
if (!string.IsNullOrEmpty(fieldAttributeValue))
        
{
            
try
            
{
                
return int.Parse(fieldAttributeValue);
            }

            
catch
            
{
                
return 0xff;
            }

        }

        
return 0xff;
    }

    
set
    
{
        
if ((value < 1|| (value > 0xff))
        
{
            
throw new ArgumentOutOfRangeException();
        }

        
base.SetFieldAttributeValue("MaxLength", Convert.ToString(value));
    }

}

 

 

采用了 internal string SetFieldAttributeValue( string attrName, string attrValue) 方法添加属性,这种属性是可以在RenderPattern用
<Property Select="MaxLength"/>引用的。但是这个方法是internal的,我们的代码无法使用。
好在我们有反射,利用反射是可以调用一个类的非公共方法的。
我们重载SPField的 OnAdded和 OnUpdated方法,当自定义属性改变时同步到字段的标准属性:

public   override   void  OnAdded(SPAddFieldOptions op)
        
{
            
base.OnAdded(op);
            SyncProperty();          
        }

        
public   override   void  OnUpdated()
        
{
            
base.OnUpdated();
            SyncProperty();
        }

        
/// <summary>
        
/// 将自定义属性同步到Property,便于在fldtypes_文件中使用
        
/// </summary>

         void  SyncProperty()
        
if (GetAttributeValue(ExportTemplate_PropertyName) == this.ExportTemplate) return//防止递归
            SetAttributeValue(ExportTemplate_PropertyName, 
this.ExportTemplate);
            
this.Update();
        }

        
/// <summary>
        
/// 设置属性值,利用反射调用基类的internal方法
        
/// fldtypes_中的RenderPattern无法调用到 CustomProperty,所有把CustomProperty同步到Property
        
/// </summary>
        
/// <param name="name"></param>
        
/// <param name="value"></param>
        
/// <returns></returns>

         protected   string  SetAttributeValue( string  name,  string  value)
        
{  Type t = typeof(SPField);            object obj = t.InvokeMember("SetFieldAttributeValue", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod,
            
nullthisnew object[] { name , value });
            
return "" + obj;
        }

        
/// <summary>
        
/// 获取属性值,利用反射调用基类的internal方法
        
/// </summary>
        
/// <param name="name"></param>
        
/// <returns></returns>

         protected   string  GetAttributeValue( string  name)
        
{
            Type t 
= typeof(SPField);            object obj = t.InvokeMember("GetFieldAttributeValue", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod,
            
nullthisnew object[] { name });
            
return "" + obj;
        }

OK,问题解决。

关于自定义字段的开发可以参考以下文章:
http://www.cnblogs.com/shangmeizhai/archive/2007/04/15/714274.html

可能大家看得有点云里雾里(懒阿,没有好好去写~),但相信这篇文章对碰到同样问题的兄弟是有价值的。

你可能感兴趣的:(Pattern)