1

I'm trying to do some script validation in a tool I wrote. The user first selects a dataframe from the current mxd. This parameter works fine. When the user makes this selection, the next parameter, a list of layers in that dataframe should populate the next parameter. But all I get with the code below is an empty list. I can get layers for the entire mxd, but am unable to restrict it to the selected dataframe. This seems like something simple I'm missing. How can I accomplish this?

def initializeParameters(self):
"""Refine the properties of a tool's parameters.  This method is
called when the tool is opened.
Populates data frame parameter with data frames in map and disables other
parameters.
"""
try:   # this works
    mxd = arcpy.mapping.MapDocument('CURRENT')
    dflist = [df.name for df in arcpy.mapping.ListDataFrames(mxd)]
    self.params[0].filter.type = "ValueList"
    self.params[0].filter.list = dflist
    del mxd
except:
    arcpy.AddError("\nMust run this tool in ArcMap, not ArcCatalog")

self.params[1].enabled = False
self.params[2].enabled = False

return



def updateParameters(self):
    """Modify the values and properties of parameters before internal
    validation is performed.  This method is called whenever a parameter
    has been changed."""

    mxd = arcpy.mapping.MapDocument('CURRENT')

    if self.params[0].value:
        self.params[1].enabled = True

        # this does not work the way I want
        layerList = [lyr.name for lyr in arcpy.mapping.ListLayers(mxd, self.params[0].value) if not lyr.isGroupLayer]

        uniqueList = list(set(layerList))
        uniqueList.sort()

        self.params[1].filter.type = "ValueList"
        self.params[1].filter.list = uniqueList
1

I think this line is wrong:

layerList = [lyr.name for lyr in arcpy.mapping.ListLayers(mxd, self.params[0].value) if not lyr.isGroupLayer]

A ListLayers() requires an mxd or a dataframe, not both. So should be

layerList = [lyr.name for lyr in arcpy.mapping.ListLayers(self.params[0].value) if not lyr.isGroupLayer]

Here is the entire updateParameters(self) function that worked for me. I had to get the Data Frame using arcpy.mapping.ListDataFrames() and then use that in the arcpy.mapping.ListLayers().

def updateParameters(self):
    """Modify the values and properties of parameters before internal
    validation is performed.  This method is called whenever a parameter
    has been changed."""
    mxd = arcpy.mapping.MapDocument('CURRENT')

    if self.params[0].value:
        self.params[1].enabled = True

        df = arcpy.mapping.ListDataFrames(mxd, self.params[0].value)[0]

        if df:
            layerList = [lyr.name for lyr in arcpy.mapping.ListLayers(df) if not lyr.isGroupLayer]
            uniqueList = list(set(layerList))
            uniqueList.sort()
            self.params[1].filter.list = uniqueList

Selecting the first Dataframe gives a list of the layers in that frame:
enter image description here

Selecting the second Dataframe then shows the list of those layers:
enter image description here

Note that if you select your dataframe, and then a layer, but then decide to change the dataframe you may see an error. This is just telling you that the currently selected layer is not in the list of layers. Selecting a valid layer will remove the error. There is probably a way to get around that error, but I didn't find it in my brief look.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.