Editing layer field properties

5415
12
12-30-2015 08:58 AM
Highlighted
New Contributor II

Hi all,

I would modify the properties of all layers in an mxd setting, for instance, all the fields as non editable.

The following script seems to work:

import arcpy   

mxd = arcpy.mapping.MapDocument('path-to-mxd')

df = arcpy.mapping.ListDataFrames(mxd,"Layers")[0]

layers = arcpy.mapping.ListLayers(mxd,"*",df)

for lyr in layers:

    print "Working on layer: " + lyr.name

    fields = arcpy.ListFields(lyr.dataSource)

    for f in fields:

        f.editable = False

mxd.save()

It runs without errors, prints all the layer names but when I open the mxd nothing has changed, the fields are still editable. By the way the mxd IS saved, I just see a new timestamp in the "last modified" property of the file.

Am I missing something?

Thank you,

Damiano

Reply
0 Kudos
12 Replies
Highlighted
MVP Esteemed Contributor

perhaps this is important

Updating a field property only updates the field object, no changes are made to the actual field in the table or feature class.
from Field—Help | ArcGIS for Desktop
implying that there is no persistence of the state outside of the field instance.

Highlighted
Regular Contributor III

I can't find how to change the field property "Make field read only" but maybe you or someone else knows. If you can change that property it will make the field non-editable.

Highlighted
MVP Esteemed Contributor

If they are standalone files, this property doesn't persist outside the project

Reply
0 Kudos
Highlighted
New Contributor II

Hi Wes,

the property I would like to change is the one outlined in red:

layer_field_properties.png

If you change this property here and then share the layer as feature service, the server will keep it disabling the editing of the field also if you enable the update capability.

Reply
0 Kudos
Highlighted
Regular Contributor II

You would need to leverage ArcObjects to accomplish this against an existing layer object. I'd assume that the code needed would be similar to the following snippet I put together.

static void MakeFieldReadonly(ESRI.ArcGIS.Carto.ILayer layer, string fieldname)

{

    // Get the fields for the layer

    var layerfields = layer as ESRI.ArcGIS.Carto.ILayerFields;

    for (int i = 0; i < layerfields.FieldCount; i++)

    {

        // Set field readonly property to true if field matches needed field

        if (layerfields.Field.Name.Equals(fieldname, System.StringComparison.InvariantCultureIgnoreCase))

            (layerfields.FieldInfo as ESRI.ArcGIS.Geodatabase.IFieldInfo3).Readonly = true;               

    }

}

From what I understand the readonly property is only valid within the client. As such, I don't believe that you'd ever be able to persist this value within the geodatabase without making the entire feature class readonly. If it were possible to set this value then I'd assume that there'd be a method available within IClassSchemaEdit, but so far I haven't seen a method available that would allow that.

Highlighted
New Contributor II

Thank you Freddie, I'll give it a try. However, I would only like to persist the changes in the mxd, not in the geodatabase. See the screenshot above and my reply to Wes on this.

Reply
0 Kudos
Highlighted
MVP Esteemed Contributor

As I indicated earlier, it persists within the arcmap session and project, the read-only preservation is not kept when the layer is added to another project

read_only_fields.png

Highlighted
New Contributor II

Of course! But with Python also this kind of persistence seems to be not achievable.

Reply
0 Kudos
Highlighted
MVP Esteemed Contributor

That is correct.  I guess we are commenting on the concept of 'persistence'

Reply
0 Kudos