Thursday, April 12, 2012

Create a Multiple-Column Lookup

The following example shows the complete code for a subclass of the SPFeatureReceiver class that creates and deletes lookup columns on the Contoso Orders list. Code in the FeatureActivated method creates a primary lookup column named Customer ID that looks up the value of the ID column on the Contoso Customers list. The code then creates secondary lookup columns for First Name, Last Name, and Phone, and it adds the secondary columns to the default view on the Contoso Orders list.
The example also includes code for the FeatureDeactivating method, which deletes all the lookup columns that are created in the FeatureActivated method. Note that you must delete all secondary lookup columns before you delete the primary lookup column on which they depend.

using System;
using System.Runtime.InteropServices;
using Microsoft.SharePoint;

namespace Contoso.Orders.Features.CustomerLookups
{
    [Guid("49e72c4b-cfcb-4665-9c2a-fdadf0a3b018")]
    public class CustomerLookupsEventReceiver : SPFeatureReceiver
    {

        // Define static field names.
        const string STATIC_CUST_ID = "CustID";
        const string STATIC_CUST_FNAME = "CustFName";
        const string STATIC_CUST_LNAME = "CustLName";
        const string STATIC_CUST_PHONE = "CustPhone";

        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            string logEntry = properties.Definition.DisplayName + " activation error: ";

            // Get an object representing either the current website (if the scope is Web)
            // or the root website (if the scope is Site).
            SPWeb web = properties.Feature.Parent as SPWeb;
            if (web == null)
            {
                SPSite site = properties.Feature.Parent as SPSite;
                if (site != null)
                    web = site.RootWeb;
            }
            if (web == null)
            {
                System.Diagnostics.Trace.WriteLine(logEntry + "Invalid scope");
                return;
            }

            // Get objects for the two lists.
            SPList customers = web.Lists.TryGetList("Contoso Customers");
            SPList orders = web.Lists.TryGetList("Contoso Orders");
            if (customers == null || orders == null)
            {
                System.Diagnostics.Trace.WriteLine(logEntry + "List not found");
                return;
            }

            // Get the fields from the Customers list that will be seen on the Orders list.
            SPField custID, custLName, custFName, custPhone;
            try
            {
                custID = customers.Fields.GetField("ID");
                custFName = customers.Fields.GetField("First Name");
                custLName = customers.Fields.GetField("Last Name");
                custPhone = customers.Fields.GetField("Contact Phone");
            }
            catch (ArgumentException ex)
            {
                // One of the fields was not found on the Customers list.
                System.Diagnostics.Trace.WriteLine(logEntry + ex.Message);
                return;
            }

            /* 
            * Create a multi-column lookup on the Orders list. 
            */

            // Create the primary column: Customer ID.
            string strPrimary = orders.Fields.AddLookup("Customer ID", customers.ID, true);

            SPFieldLookup primary = orders.Fields.GetFieldByInternalName(strPrimary) as SPFieldLookup;
            primary.LookupField = custID.InternalName;
            primary.StaticName = STATIC_CUST_ID;
            primary.Update();

            // Create a secondary column: First Name.
            string strFName = orders.Fields.AddDependentLookup("First Name", primary.Id);

            SPFieldLookup ordersFName = orders.Fields.GetFieldByInternalName(strFName) as SPFieldLookup;
            ordersFName.LookupField = custFName.InternalName;
            ordersFName.StaticName = STATIC_CUST_FNAME;
            ordersFName.Update();

            // Create a secondary column: Last Name.
            string strLName = orders.Fields.AddDependentLookup("Last Name", primary.Id);

            SPFieldLookup ordersLName = orders.Fields.GetFieldByInternalName(strLName) as SPFieldLookup;
            ordersLName.LookupField = custLName.InternalName;
            ordersLName.StaticName = STATIC_CUST_LNAME;
            ordersLName.Update();

            // Create a secondary column: Phone.
            string strPhone = orders.Fields.AddDependentLookup("Phone", primary.Id);

            SPFieldLookup ordersPhone = orders.Fields.GetFieldByInternalName(strPhone) as SPFieldLookup;
            ordersPhone.LookupField = custPhone.InternalName;
            ordersPhone.StaticName = STATIC_CUST_PHONE;
            ordersPhone.Update();

            // Add columns to the default view.
            AddToDefaultView(orders, strFName);
            AddToDefaultView(orders, strLName);
            AddToDefaultView(orders, strPhone);
        }

        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            string logEntry = properties.Definition.DisplayName + " deactivation error: ";

            // Get an object representing either the current website (if the scope is Web)
            // or the root website (if the scope is Site).
            SPWeb web = properties.Feature.Parent as SPWeb;
            if (web == null)
            {
                SPSite site = properties.Feature.Parent as SPSite;
                if (site != null)
                    web = site.RootWeb;
            }
            if (web == null)
            {
                System.Diagnostics.Trace.WriteLine(logEntry + "Invalid scope");
                return;
            }

            // Get the Orders list.
            SPList orders = web.Lists.TryGetList("Contoso Orders");
            if (orders == null)
            {
                System.Diagnostics.Trace.WriteLine(logEntry + "List not found");
                return;
            }

            // Delete the lookup fields.
            // Note that you must delete dependent lookup fields
            // before deleting the primary lookup field.
            SPFieldLookup primaryLookup = orders.Fields.TryGetFieldByStaticName(STATIC_CUST_ID) as SPFieldLookup;
            if (primaryLookup != null && !primaryLookup.IsDependentLookup)
            {
                string[] dependentLookupNames = primaryLookup.GetDependentLookupInternalNames().ToArray();
                if (dependentLookupNames.Length != 0)
                {
                    foreach (string dependent in dependentLookupNames)
                    {
                        orders.Fields.Delete(dependent);
                    }
                }
                primaryLookup.Delete();
            }

        }

        public void AddToDefaultView(SPList list, string fieldName)
        {
            if (list != null && list.Fields.ContainsField(fieldName) && !list.DefaultView.ViewFields.Exists(fieldName))
            {
                SPView defaultView = list.DefaultView;
                defaultView.ViewFields.Add(fieldName);
                defaultView.Update();
            }
        }
    }
}

No comments:

Post a Comment