Creating lookup-fields only via XML-Definition is not possible. You need the ID of the Web hosting the list and the ID of the list hosting the data the lookup field is connected to. This information can only be retrieved when both entities are created…
Object model?!
When looking into the SPFieldLookup-class you find the properties LookupField, LookupList and LookupWebId. LookupWebId and LookupField can easily be set via the object model. The documentation says that LookupList is read and writeable which is not true. Setting LookupList throws an exception stating out “Cannot change the lookup list of the lookup field.”.
SchemaXml and Regex to the rescue
The SchemaXml-property of a SPField can be used to manipulate the LookupList. One stumbling block is that you do not know the Guid of the LookupList currently stored in the schema. Even if you define a Guid inside your xml-field-definition SharePoint puts in an other Guid. Here a simple regular expression comes to help.
The code for connecting a site-column with a list somewhere in some web:
// Declarations (myWeb is the context given by a feature receiver scoped "web") var rx = new Regex("List=\"([^\"]*)\"", RegexOptions.IgnoreCase | RegexOptions.ECMAScript); var root = myWeb.Site.RootWeb; // myListInstance is an instance of a SPList existing somewhere var lookupField = (SPFieldLookup)root.Fields["MyLookupField"]; var xml = lookupField.SchemaXml; xml = rx.Replace(xml, String.Format("List=\"{0}\"", myListInstance.ID.ToString("B"))); lookupField.SchemaXml = xml; // Do not call update here! // Quote from MSDN "Do not call the Update method when using the SchemaXml property to modify a field." // Fetch the field again and apply the web-id var lookupFieldReFetch = (SPFieldLookup)root.Fields["MyLookupField"]; lookupFieldReFetch.LookupWebId = myWeb.ID; lookupFieldReFetch.LookupField = "Title"; lookupFieldReFetch.Update(true); |
This problem still persists in the beta of SharePoint 2010. I hope this will get fixed in the RTM. Creating a lookup-field-connection is far more easy by the way …