Setting the Title field for Content Types

This is one I’ve been meaning to blog about for a while. I was using a Content Type where I was trying to set the display name of ‘Title’ field. I was happy to have a Title column, but I wanted it to have a different name.

I tried doing this declaratively:

<FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" DisplayName="Request" Required="FALSE" />

However, I found this didn’t work in SP2010 – the field still appeared as ‘Title’. This was frustrating.

Instead, I had to set the Title’s display name in code:

foreach (SPFieldLink fldLnk in contentType.FieldLinks)
{
if (fldLnk.Id == SPBuiltInFieldId.Title)
{
fldLnk.DisplayName = "Request";
}
}
contentType.Update(false);

This was a bit strange – other fields can have a DisplayName set in CAML quite happily. This seems to just be a feature of the Title column.

EDIT: I also had to use a similar approach on setting the Title column for a content type used on a list – but using:

private void SetTitleField(SPWeb web, string listname, string contentTypeName, string newTitleName) 
{
SPList list = web.Lists[listname];
SPContentType ct = list.ContentTypes[contentTypeName];

foreach (SPFieldLink fldLnk in ct.FieldLinks)
{
//Necessary to set title field - when using content types, this seems to set it to "Title" irrespective of what is set in the Content type or list's XML.
if (fldLnk.Id == SPBuiltInFieldId.Title)
{
	fldLnk.DisplayName = newTitleName;
	ct.Update(false);
	break;
}
}
foreach (SPField fld in list.Fields)
{
if (fld.Id == SPBuiltInFieldId.Title)
{
	fld.Title = newTitleName;
	fld.Update();
	break;
}
}     
}

BeforeProperties and AfterProperties

I am sick of having to hunt down the link to Synergy’s post on the BeforeProperties and AfterProperties available in different events on SPListItems. For my reference, here it is:

List:

List BeforeProperties AfterProperties properties.ListItem
ItemAdding No value New value Null
ItemAdded No value New value New value
ItemUpdating No value Changed value Original value
ItemUpdated No value Changed value Changed value
ItemDeleting No value No value Original value
ItemDeleted No value No value Null

Document Library:

Library BeforeProperties AfterProperties properties.ListItem
ItemAdding No value No value Null
ItemAdded No value No value New value
ItemUpdating Original value Changed value Original value
ItemUpdated Original value Changed value Changed value
ItemDeleting No value No value Original value
ItemDeleted No value No value Null

Note: Allegedly, this does change if the event receiver is synchronous - the before properties are available. I’ve not checked this out yet.

Obviously, for SharePoint 2007 systems that doesn’t apply – as ‘*ed’ event receivers are always asynchronous.

ContentIterator – Curious Behaviour, and Infinite looping

I like the ContentIterator control – it’s a nice way of being able to process a lot of items in SharePoint. However, sometimes it’s behaviour is … strange.

I had been using it to loop over some (but not all) the items in a list. Some changes meant that I was now going to loop over all the items. I had a list with 500 items that I was testing with. My code was:

ContentIterator ci = new ContentIterator("example");
SPQuery qry = new SPQuery();
qry.Query = ContentIterator.ItemEnumerationOrderByNVPField;
ci.ProcessListItems(list,qry, ProcessItem, ProcessItemError);

This would process the first 200 items, over and over. It never reached an end. Hmm. Continue reading

Delete Event Receiver from a Content Type with Code

SharePoint allows you to attach event receivers to content types. That’s pretty handy. Unfortunately, deleting event receivers from those content types is much more hard. Perhaps this is why the Document ID feature fails to remove the content types that it adds. However, here is one possible approach.

SPContentType ctype = site.RootWeb.ContentTypes[SPBuiltInContentTypeId.Document];
if (ctype != null)
{
 if (ctype.EventReceivers != null)
 {
   bool bContinueDelete = true;
   while (bContinueDelete)
   {
     if (ctype.EventReceivers.Count < 1)
     {
       bContinueDelete = false;
     }
     else
     {
     bool bFoundOne = false;
     foreach (SPEventReceiverDefinition d in ctype.EventReceivers)
     {
         //Could match on the Type of the event receiver, but for this example, let's use name
         if (d.Name.Contains("Document ID"))
         {
           d.Delete();
           ctype.Update(true, false);
           bFoundOne = true;
           break;
         }
     }
     if (!bFoundOne)
     {
       bContinueDelete = false;
     }
   }
 }
}

More on why this is important in a later post.

Strange issue with Application Page and Two Button Presses

Okay, this one was weird. The symptom is this – I had a custom Application page that was being used as the New and Edit forms for a particular custom list in my solution. One of the customisations was that it had an ‘Address Search’ button that, when you pressed, searched for an address based on the first line of the address, or the postcode.

That’s fine, but here’s where things got weird.

  • If you were using the form as a New form, then search worked just fine the first time you clicked it.
  • If you were using the form as an Edit form, the the search button didn’t work the first time you use it – but did the second time you clicked on it.

Bizarre, and I had to fix it… Continue reading