Python Toolbox - Only update parameter when specific parameter changes

The "arcpy way ™" is to check if parameters[0].altered and not parameters[0].hasBeenValidated:

According to the documentation:


altered is true if the value of a parameter is changed... Once a parameter has been altered, it remains altered until the user empties (blanks out) the value, in which case it returns to being unaltered.


hasBeenValidated is false if a parameter's value has been modified by the user since the last time updateParameters and internal validate were called. Once internal validate has been called, geoprocessing automatically sets hasBeenValidated to true for every parameter.

hasBeenValidated is used to determine whether the user has changed a value since the last call to updateParameters.

For example, a simplified version of your code (doesn't disable/enable, just empties/populates parameters[2]):

import arcpy

class Toolbox(object):
    def __init__(self):
        """Define the toolbox (the name of the toolbox is the name of the
        .pyt file)."""
        self.label = "Toolbox"
        self.alias = ""

        # List of tool classes associated with this toolbox = [Tool]

class Tool(object):
    def __init__(self):
        self.label = "Tool"
        self.description = "A Tool"
        self.canRunInBackground = False

    def getParameterInfo(self):
        inGdb = arcpy.Parameter(
            displayName = "Input Geodatabase",
            name = "ingdb",
            datatype = "DEWorkspace",
            parameterType = "Required",
            direction = "Input")
        # Set the filter to accept only local geodatabases
        inGdb.filter.list = ["Local Database"]

        outGdb = arcpy.Parameter(
            displayName = "Output Geodatabase",
            name = "outgdb",
            datatype = "DEWorkspace",
            parameterType = "Required",
            direction = "Input")
        # Set the filter to accept only local geodatabases
        outGdb.filter.list = ["Local Database"]

        inFcs = arcpy.Parameter(
            displayName = "Feature Classes And Tables",
            name = "infcs",
            datatype = "GPString",
            parameterType = "Required",
            direction = "Input",
            multiValue = True)

        return [inGdb, outGdb, inFcs]

    def updateParameters(self, parameters):

        if not parameters[0].altered:

            parameters[2].filter.list = []
            parameters[2].value = None

        elif parameters[0].altered and not parameters[0].hasBeenValidated:

            gdb = parameters[0].valueAsText
            arcpy.env.workspace = gdb
            fcs = []
            for typ in ["Point", "Polygon", "Polyline", "Multipoint"]:
                fcs += ["{} (Feature Class)".format(fc) for fc in arcpy.ListFeatureClasses(feature_type = typ)]
            fcs += ["{} (Table)".format(tab) for tab in arcpy.ListTables()]
            datasets = arcpy.ListDatasets()
            for dataset in datasets:
                for typ in ["Point", "Polygon", "Polyline", "Multipoint"]:
                    dsFcs = arcpy.ListFeatureClasses(None, typ, dataset)
                    for dsFc in dsFcs:
                        fc = os.path.join(dataset, dsFc)
                        fcs += [fc]
            parameters[2].filter.list = fcs

For this one a use of a global variable will help:

currentValue = '' # to avoid problems later give it an empty string

def updateParameters(self, parameters):
  global currentValue
  if parameters[0].valueAsText != currentValue:
    currentValue = parameters[0].valueAsText
    # the rest of your code

Python is a bit finicky about that sort of thing, if you don't tell it you want to use the existing global variable it will assume that it's a new local variable (which has a value of None).

Global variables are handy and have a purpose but I would warn future readers of this post to not over-use global variables.. I have read some articles that suggest that globals in python chew up memory needlessly.