Ah, the danger of the Internet. I hit this problem – trying to update a field built-in to a content type (the Title field) so that it was hidden from the UI. Easy I thought, get the SPWeb, get the SPContentType, find the field (ct.Fields[“Title”]), set it to hidden and update it. Nope.
Exception: This functionality is unavailable for fields not associated with a list
Engaging my brain / memory resolved this, but not before I encountered numerous “helpful” posts on the web about how what I was trying to do was not possible. One such example here, which categorically stated…
It does make sense. You can only change the field on a per list (or globally) scope; you can not do it per content type.
This immediately smelled fishy to me – because you can do exactly this thing via the UI. So don’t always believe what you read on the Internet. (This blog notwithstanding, obviously.)
And for those looking for the answer, the correct way is to modify the .FieldLinks collection:
var ct = web.ContentType["YourCustomContentType"]; var field = ct.FieldLinks["Title"]; field.Hidden = true; ct.Update(true); // this will push the change to lists using the CT
A quick note on that first line of code…
While I’m here, this line requires a little discussion.
var ct = web.ContentType["YourContentType"];
As you may know, there are two collections of ContentType available to you… “web.AvailableContentTypes” and “web.ContentTypes”. So what is the difference? Put simply, .ContentTypes are the CTs within the current SP object, in this case SPWeb. So it’s all that web’s content types. Whereas .AvailableContentTypes is all within the current scope, so the current SPWeb, and any of its subwebs.
BUT… and the reason for this is .AvailableContentTypes is a read-only collection. I.e., you cannot use it to add new Content Types to your SPWeb. So if that’s what you’re trying to do, make sure you use .ContentTypes.