Sharepoint имеет два типа полей, предназначенных для вывода вычислимых значений на формах просмотра элемента списка – computed и calculated. Поля с типом calculated сохраняют свое значение в базе данных и обновляют его только при обновлении элемента списка. Поэтому это поле не может использоваться для отображения данных, которые могут изменитья независимо от элемента списка. Поле типа computed вычисляет формулу , состоящую из значений других полей элемента списка. Разработчики не могут создавать пользовательские поля, наследующие этот тип поля (SPFieldComputed) и могут использовать только caml для задания формулы в схеме.
Поставленная задача – отображение в форме просмотра списка (обычно это dispform.aspx, но в принципе имя формы задается в схеме списка) данных, которые с одной стороны зависят от текущего элемента списка, а с другой независимы от него (в элементе списка item1 есть ссылка на другой элемент списка item2 и надо вывести, например, имя item2 в верхнем регистре).
Решение в целом:
Создать пользовательское поле, наследуемое от SPFieldText и переопределить метод RenderFieldForDisplay класса control, который отображает это поле.
Решение в деталях:
1. Создать проект visual studio с типом class library и создать новый класс:
// example of creating a custom field type
public class SomeCustomField : SPFieldText
{
public SomeCustomField(SPFieldCollection fields, string fieldName)
: base(fields, fieldName) { }
public SomeCustomField(SPFieldCollection fields, string typeName, string displayName)
: base(fields, typeName, displayName) { }
public override Microsoft.SharePoint.WebControls.BaseFieldControl FieldRenderingControl
{
get
{
BaseFieldControl control = new SomeCustomFieldControl();
control.FieldName = this.InternalName;
return control;
}
}
}
// custom field type uses helper class to initialize and render control
public class SomeCustomFieldControl : BaseFieldControl
{
protected override string DefaultTemplateName
{
get
{
return @”SomeCustomFieldControl”;
}
}
protected override void RenderFieldForDisplay(HtmlTextWriter output)
{
int IdOfItem2 = (int)this.ListItem["refid"];
SPListItem item2 = this.ListItem.ParentList.GetItemById(IdOfItem2);
string data = item2.Name.ToUpper();
output.Write(data);
base.RenderFieldForDisplay(output);
}
}
2.Откомпиллировать класс, создать сборку, подписать ее, и разместить в GAC.
(Как все просто в sharepoint )
3.Создать SomeCustomField.ascx со следующим содержанием:
<SharePoint:RenderingTemplate ID=”SomeCustomFieldControl” runat=”server”>
<Template>
</Template>
</SharePoint:RenderingTemplate>
Скопировать этот файл в директорию Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\CONTROLTEMPLATES
3. Созать файл fldtypes_SomeCustomField.xml со следующим содержанием:
<?xml version=”1.0? encoding=”utf-8 ?>
<FieldTypes>
<FieldType>
<Field Name=”TypeName”>SomeCustomField</Field>
<Field Name=”ParentType”>Text</Field>
<Field Name=”TypeDisplayName”>SomeCustomField Status</Field>
<Field Name=”TypeShortDescription”>SomeCustomField Status Field</Field>
<Field Name=”UserCreatable”>TRUE</Field>
<Field Name=”ShowInListCreate”>TRUE</Field>
<Field Name=”ShowInSurveyCreate”>TRUE</Field>
<Field Name=”ShowInDocumentLibraryCreate”>TRUE</Field>
<Field Name=”ShowInColumnTemplateCreate”>TRUE</Field>
<Field Name=”FieldTypeClass”>SomeCustomFieldAssembly.SomeCustomField, SomeCustomField, Version=1.0.0.0, Culture=neutral, PublicKeyToken=11ae1111111ddd11</Field>
<RenderPattern Name=”DisplayPattern”>
<Switch>
<Expr>
<Column/>
</Expr>
<Case Value=”»>
</Case>
<Default>
<Column SubColumnNumber=”0? HTMLEncode=”TRUE”/>
</Default>
</Switch>
</RenderPattern>
</FieldType>
</FieldTypes>
Скопировать его в папку Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\XML
4. Инсталлировать и активировать feature.xml:
<?xml version=”1.0? encoding=”utf-8? ?>
<!– _lcid=”1033 _version=”12.0.4017 _dal=”1 –>
<!– _LocalBinding –>
<Feature Id=”11111111-1111-1111-85B9-5ED1D39C073B”
Title=”CustomField”
Description=”SomeCustomField Type”
Version=”12.0.0.0?
Scope=”Site”
xmlns=”http://schemas.microsoft.com/sharepoint/” >
<ElementManifests>
<ElementManifest Location=”elements.xml”/>
</ElementManifests>
</Feature>
where the elements.xml is:
<Field ID=”{CA1A1D11-2123-4db7-B11A-1C0D05D01111}”
Name=”SomeCustomFieldDerived”
Group=”Custom”
Type=”SomeCustomField”
DisplayName=”SomeCustomField Derived”
ShowInDisplayForm=”TRUE”
Sortable=”FALSE”
ReadOnly=”TRUE”
Required=”false”
Hidden=”false”
SourceID=”http://schemas.microsoft.com/sharepoint/v3”
StaticName=”SomeCustomFieldDerived”
/>
Все сделано. Теперь можно добавлять наше поле к элементам списка или типам содержимого.
К этому полю нельзя будет делать caml запросы и реальное значение этого поля в элементах списка будет null, соответственно оно не будет отображаться на странице просмотра всех элементов списка allitems.aspx.