Martin's profileMartin Hatch {Tales from...PhotosBlogListsMore ![]() | Help |
|
13 October [Code Update] SDK and Microsoft Press Both Wrong?? Custom Fields in the schema.xmlUPDATE
For those who missed my original article (SDK and Microsoft Press Both Wrong?? Custom Fields in the schema.xml) , you can find it here!
I finally got round to posting the code that goes with this article ..
Please find below the details on code for an SPFeatureReceiver class, that will automatically push down changes from your Content Type Features
(you will need to attach the code to your feature using the ReceiverAssembly and ReceiverClass attributes in your feature.
The code needs to be created as a Class in a Class Library, with Microsoft.SharePoint.dll added as a reference, and then added as a Using statement in the class itself.
Code Sample
EDIT - Thanks to a quick spot from Nick's SharePoint blog, I have updated the code to match! Thanks Nick!
ContentTypeInstaller : SPFeatureReceiver {
// CODE DESCRIPTION // ---------------- /* * This is a feature handler which should be paired
* with a content type feature.
*
* We have identified a problem with Content Types,
* where the content type site columns are not pushed
* down to custom list definitions, until they are
* "modified" first.
*
* This feature will interrogate all of the associated
* xml files that are attached to the feature.
* Once found, it will "modify" each of the custom fields
* that are referenced.
*
* This should allow list definitions to use the content
* type columns, without declaring them in the schema.xml
*/
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
using(SPSite site = (SPSite)properties.Feature.Parent)
{
SPWeb web = site.OpenWeb( "");
// loop through each of the elements in the feature
foreach (SPElementDefinition element in properties.Definition.GetElementDefinitions(CultureInfo.CurrentCulture))
{
#region Loop through feature elements
XmlNode content = element.XmlDefinition;
// only continue if the element is a content type definition
if (content.Name == "ContentType")
{
// grab a new Content Type object
string strCTypeID = content.Attributes["ID"].Value;
SPContentType cType = web.ContentTypes[ new SPContentTypeId(strCTypeID)];
#region Get FieldRef Order from Content type
// grab the original order, we will need this later
string[] fieldOrder = new string[cType.FieldLinks.Count];
int x = 0;
foreach (SPFieldLink fieldlink in cType.FieldLinks)
{
fieldOrder[x] = fieldlink.Name;
x++;
}
#endregion
#region Add new columns to the content type
// loop through each sub-node in the Content Type file
foreach (XmlNode node in content.ChildNodes)
{
#region loop through sub nodes
// only continue for
// the FieldRefs collection
if (node.Name == "FieldRefs")
{
foreach (XmlNode fieldRef in node.ChildNodes)
{
#region Loop through FieldRefs
// only apply for FieldRef tags
if (fieldRef.Name == "FieldRef")
{
// get the FieldID and use it to
// retrieve the SPField object
string fieldID = fieldRef.Attributes["ID"].Value;
//SPFieldLink fieldLink = cType.FieldLinks[new Guid(fieldID)];
SPField field = cType.Fields[ new Guid(fieldID)];
// first we need to remove the fieldref
cType.FieldLinks.Delete( new Guid(fieldID));
// and save, pushing this change down
cType.Update( true);
// NOTE - this will NOT delete any content
// in existing lists!
// now add the field back in again
cType.FieldLinks.Add( new SPFieldLink(field));
// and call an update, pushing down all changes
cType.Update( true);
// NOTE - this is what adds the column to those
// lists who don't already have it.
}
#endregion
}
}
#endregion
}
#endregion
#region Apply changes
// reset the field order
// it is possible that adding and
// removing fields would have
// affected this
cType.FieldLinks.Reorder(fieldOrder);
// force update of the content type,
// pushing down to children
cType.Update( true);
#endregion
}
#endregion
}
}
}
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
}
public override void FeatureInstalled(SPFeatureReceiverProperties properties)
{
}
public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
{
}
}
Enjoy, and happy coding! Comments (9)
Martin Hatch
has turned off comments on this page.
Trackbacks (6)The trackback URL for this entry is: http://mkeeper.spaces.live.com/blog/cns!60F12A60288E5607!280.trak Weblogs that reference this entry
|
|
|