字段配置文件如下:
FieldTypes
PropertySchema中声明了一个自定义属性:ExportTemplate,但是这个属性无法在RenderPattern中引用,如上面配置文件的写法,
<Property Select="ExportTemplate"/>输出始终为空。
反射系统的SPFileText的实现,它声明了类似的MaxLength等属性:
MaxLength
采用了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,
null, this, new 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,
null, this, new object[] { name });
return "" + obj;
}
{
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,
null, this, new 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,
null, this, new object[] { name });
return "" + obj;
}
OK,问题解决。
关于自定义字段的开发可以参考以下文章:
http://www.cnblogs.com/shangmeizhai/archive/2007/04/15/714274.html
可能大家看得有点云里雾里(懒阿,没有好好去写~),但相信这篇文章对碰到同样问题的兄弟是有价值的。