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
Midavalo
30k11 gold badges53 silver badges108 bronze badges
asked Jan 15, 2018 at 16:01

1 Answer 1

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.

answered Jan 15, 2018 at 17:15

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.