Hidden fields, and controlling them with the Object Model

SharePoint’s fields can be ‘hidden’ or shown, by setting the SPField.Hidden property. That’s great, but sadly it isn’t that simple. You might want a field hidden, but allow administrators, etc., to ‘unhide’ the field. Then again, sometimes you might want your hidden field to be really hidden, and never ‘unhidden’.

That is actually what SharePoint allows. The SPField.Hidden property also relies on a second property ‘CanToggleHidden’. You can see this in the CAML definition of a field. So you could define a field like:

<Field Type="Text" ID="{449cf8bc-88ce-445a-ac55-11ea0cb71fed}" Hidden="TRUE" CanToggleHidden="TRUE" ... >

Okay, that’s fine – that’d give us a field which is hidden, but we can unhide. Note that by default CanToggleHidden is false, and this led to my problem.

I had a bunch of fields, which were already in use, and hidden. I wanted to unhide them. I’d not set CanToggleHidden to true, and when I tried to set

 SPField.Hidden=false

I kept get an exception. Reflector shows why:

If you take a look at that, you’ll see that the setter on the Hidden property checks CanToggleHidden, and throws an exception if it’s false. So I tried to set CanToggleHidden through the object model – except that you can’t. There is no setter method for it – you can get the value, but not set it.

How to deal with this? Well, there is a clue in the Reflector output – curiously, for no logical reason I can see, at the end of the Hidden property setter it also sets CanToggleHidden property to true (which is pointless; you’ll never run that line unless the property is already true):

this.SetFieldBoolValue("CanToggleHidden", true);

Excellent! So all I need to do is call that internal method – thank God for reflectance:

public static void AllowHiddenToggle(SPField field, bool Allowed)
{
 Type type = field.GetType();
 MethodInfo mi = type.GetMethod("SetFieldBoolValue", BindingFlags.NonPublic | BindingFlags.Instance);
 mi.Invoke(field, new object[] { "CanToggleHidden", Allowed });
 field.Update();
}

So, this method will let me set CanToggleHidden to true, and I can then set the Hidden property.

This would be much better if rather that having two booleans we had an enum – “Shown, Hidden and ReallyHidden” or something.

Edit: After figuring all this out, I found a good post about it. Typical.

Advertisement
Hidden fields, and controlling them with the Object Model

5 thoughts on “Hidden fields, and controlling them with the Object Model

  1. Rodrigo says:

    Thanks Andy!
    Worked great! I had the exact same problem and this did the magic 🙂
    Glad you posted this, because you explained it much simpler and clearer than the other blog post you mentioned.

  2. Perfect, that’s what I was looking for. Wonder why they didn’t gave CanToggleHidden a setter. Thanks a million!

  3. Irfan says:

    @irfan: Very helpful artical. Thanks.

    I also tried and found another simple solution that works fine as well.
    SPField.ShowInEditForm = 1;
    SPField.ShowInNewForm = 1;
    SPField.ShowInDisplayForm = 1;
    SPField.ShowInListSettings = 1;
    SPField.ShowInVersionHistory = 1;
    SPField.ShowInViewForms = 1;
    SPField.Update();

  4. The Reflection method works, but the problem is that it is “not supported” by Microsoft and would mean that at least in theory, all warranties would be off.

    However, it’s easy to fix this by changing the field’s Schema XML using published API’s; that can be done with managed code, Powershell or even the Client Object Model i.e. with a bit of JavaScript.

    Here’s how to do that using Powershell:

    #Get the Web, List and Field
    #Then change schema XML:
    $currentXML = $field.SchemaXML

    #Remove the node if it exists, and add again
    $newXml = $currentXML.Replace(‘CanToggleHidden=”FALSE”‘,”);
    $newXml = $currentXML.Replace(‘Hidden=”TRUE”‘, ‘Hidden=”FALSE” CanToggleHidden=”TRUE”‘);

    $field.SchemaXML = $newXML
    $field.Update()

    Regards,
    Pauli

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.