One of the things we`re doing at my company with some many SharePoint projects over years is seal custom functionality as Framework Features and deploy them in a separate WSP. When a new project comes on we`re just calling various features. One of the things we noticed is that some of the features have lists used in them with field definitions and in many cases Choice fields. The problem with choice fields is that if you need to add one extra choice or delete some of them – you have to define your own list in order to have your entire solution deployed as a package. Alternatively you could ask your client and manually change the choices in your lists – but this takes away from the package presentation of your solution.
The solution to the problem is to leverage feature with an event receiver which will modify your choices based on activation properties that have been passed on it.
Here is how my feature receiver class will look like, FeatureActivated:
using (SPWeb web = properties.Feature.Parent as SPWeb)
{
string allowedChoices = string.Empty;
string listName = string.Empty;
string fieldName = string.Empty;
string[] allowedChoicesArray = null;
bool clearExisting = false;
if (properties.Feature.Properties["AvailableChoices"] != null)
{
allowedChoices = properties.Feature.Properties["AvailableChoices"].Value;
allowedChoicesArray = allowedChoices.Split(‘;’);
}
if (properties.Feature.Properties["ListName"] != null)
{
listName = properties.Feature.Properties["ListName"].Value;
}
if (properties.Feature.Properties["FieldDisplayName"] != null)
{
fieldName = properties.Feature.Properties["FieldDisplayName"].Value;
}
if (properties.Feature.Properties["ClearExistingChoices"] != null)
{
clearExisting = properties.Feature.Properties["ClearExistingChoices"].Value.ToLower().Equals(“true”);
}
SPList list = web.Lists[listName];
SPField field = list.Fields[fieldName];
if (fieldName != null)
{
SPFieldChoice choiceField = (SPFieldChoice)field;
if (clearExisting)
{
choiceField.Choices.Clear();
}
for (int i = 0; i < allowedChoicesArray.Length; i++)
{
choiceField.Choices.Add(allowedChoicesArray[i]);
}
}
}
Essentially I get a hold of the activation properties of my feature: properties.Feature.Properties["AvailableChoices"]
and the use SPFieldChoice.Choices.Add(string) to add new choices.
Enjoy!