This Microsoft Office Visual How To demonstrates how you can extend a custom Relationship field in Microsoft Office SharePoint Server 2007 to retrieve and display document relationships from a secondary list by using a field control.
For information about how to create the custom Relationship field and the secondary list for defining and storing document relationships, see the following Office Visual How Tos:
When the control is in display mode, the relationship information is retrieved from the Relationship Lookup list, formatted, and displayed in the control. Retrieval and display of the relationship information is done in the Render method.
The first step is to retrieve the relationship information for this document from the Relationship Lookup list. The Relationship Lookup list stores the GUIDs for each document in the item 1 and item 2 fields. A query is used to retrieve all items in a list item collection from the Relationship Lookup list where the value in item 1 or item 2 equals the GUID of the current document.
The next step is to obtain the related document and list GUIDs from the list item collection. A check is made to see whether the value for item 1 or item 2 equals the GUID for the current document. If it matches, the other item contains the GUID that represents the related document.
The final step is to obtain the display information for the related document and output it in the control. In this example, you display the document name and relationship type as a hyperlink to the related document display page.
protected override void Render(HtmlTextWriter output)
// If this is edit mode and has a value then set the picker.
&& this.ListItemFieldValue != null)
this.urlSelector.AssetUrl = this.ListItemFieldValue.ToString();
else if (base.ControlMode.Equals(SPControlMode.Display))
// Get all corresponding relationships.
SPList list = this.Web.Lists["Relationship Lookup"];
SPQuery query = new SPQuery();
string queryFormat = "<Where><Or><Eq><FieldRef
query.Query = string.Format(queryFormat,
foreach (SPListItem item in listItems)
string relatedItemUniqueId = string.Empty;
string relatedListId = string.Empty;
string relationship = string.Empty;
// Get the related list and item IDs.
if (!(item["Relationship_x0020_Type"] == null))
= new SPFieldLookupValue(item["Relationship_x0020_Type"].ToString());
// Get the related item title and URL.
SPList relatedList = this.Web.Lists[new Guid(relatedListId)];
= relatedList.Items[new Guid(relatedItemUniqueId)];
+ "?ID=" + relatedItem.ID.ToString();
// Output the link.
+ this.Web.Url + relatedItemUrl + "'>"
+ relatedItem.Name + "(" + relationship + ")" + "</a>");
Because the values are stored in a secondary list and not within the field value, you can dynamically retrieve and display them after the relationship is created without having to update the related document. The field control gives you great flexibility in how you format and display this information, whether it is contained within the field, in a separate list, or a combination of both.
You can further modify this example to extend the edit mode of the control and let users edit and manage existing relationship information.
In an implementation, one scenario that you should account for is when one of the documents in the relationship is deleted, resulting in a dead link and the requirement to clean up the relationship information in the lookup list. One solution would be to validate and clean up the relationship information within the custom field control. This would ensure that only the existing relationships are displayed. You could also use the ItemDeleted event handler to perform the cleanup when a document is deleted. Additionally, you should apply indexes to the columns that are used in the query to optimize performance.