Are some properties missing from SPFieldLink?
When you try to construct data relationship structure in SharePoint, at some point you might notice that
SPFieldLink is missing the two boolean flags known from
ShowInNewForm. To make it more confusing, the
ShowInDisplayForm flag is available and exposed as a public property.
Should the missing properties be available? That’s clearly what developers expect. Moreover, MSDN documentation displays those properties in example on the SPFieldLink.SchemaXML documentation page. Also,
SPField object contains private fields for
ShowInNewForm. Is it just a mistake that those fields weren’t exposed as public properties, or the functionality is just not implemented in SharePoint 2013?
Figure 2 illustrates the problem. When the list is created, developer might expect that the values in list’s
SPField‘s properties like
ShowInEditForm will be taken from ContentType
FieldLinks, not site
For my money, this is just an unfinished implementation due to deadlines or other problems. The better question is, what to do now if you need this functionality in your project?
Idea #1: set private fields values using reflection (does not work)
We may try to force setting the values for private fields (that exist in
SPFieldLink) with code similar to the following:
SPFieldLink fieldLink = new SPFieldLink(web.AvailableFields.GetFieldByInternalName("someFieldName"));
// get private fields
FieldInfo fld1 = fieldLink.GetType().GetField("m_bShowInEditForm", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.GetField);
FieldInfo fld2 = fieldLink.GetType().GetField("m_bEditFormExplicit", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.GetField);
// set value for ShowInEditForm private field
bool showInEditForm = false;
// make this atribute explicitly appear in SchemaXml, even if value is the default value
At this point,
fieldLink.SchemaXml variable will explicitly contain
ShowInEditForm attribute in XML. It seems that we’re at home, but… when you create list instance based on this content type, this value will just be ignored. By the way,
ShowInDisplayForm that is a public property in
SPFieldLink is also ignored.
Idea #2: create different fields on the SPWeb.Fields level
This “solution” is to let go
SPFieldLink and just create more
SPFields with the same display name. Some of them will have the
ShowInEditForm property set to
true, some to
false. Then, when creating content types, just add the field with desired property set. The list using this content type will inherit property values from
In result, display, edit and new forms will look as expected for user. Data structure will be less clear however, because some fields that are logically the same, will have multiple instances in
SPWeb.Fields collection. It will appear in site columns gallery that there are duplicates of those columns.
Idea #3: set the values on a list
Another way to do this, is not to rely on any inherited values for those properties, but set them explicitly in
SPList.Fields collection, after the list is created and content types are added to list.
Lists are likely to be created during deployment process, so this could be done in some C# code or in PowerShell after the structure is deployed.
Summary. Where’s the good solution?
None of those solutions seems satisfying, and the will not replace the missing SharePoint functionality. I wrote this overview so you can save some time doing research on the same problem. If you manage to find a better fix than aforementioned #2 or #3, please share your idea in comments 🙂