import arcpy import pythonaddins class ComboBoxClass1(object): """Implementation for Comboboxes_addin.combobox (ComboBox)""" def __init__(self): self.items = ["Forestry", "OW", "Urban", "Fire", "ED/PR", "PD", "Media"] self.editable = False self.enabled = True self.dropdownWidth = 'WWWWWW' self.width = 'WWWWWW' def onSelChange(self, selection): if selection == "Forestry": combobox_1.items = ["SP", "SPR", "MP", "AR", "ARO", "ATF", "ATN", "ACF", "TT", "RC", "RV", "AIR", "AP", "FHS", "FSU", "BMP"] combobox_1.value = combobox_1.items[0] elif selection == "OW": combobox_1.items = ["AOS", "AO", "AIO", "PO", "TGO", "TRO"] combobox_1.value = combobox_1.items[0] def onEditChange(self, text): itemsarray = ["Forestry", "OW", "Urban", "Fire", "ED/PR", "PD", "Media"] if text not in itemsarray: combobox_1.items = [" ", " ", "", " ", "", "", "", "", "", "", "", "", "", "", "", ""] def onFocus(self, focused): pass def onEnter(self): pass def refresh(self): pass class ComboBoxClass2(object): """Implementation for Comboboxes_addin.combobox_1 (ComboBox)""" def __init__(self): self.items = [" ", " ", "", " ", "", "", "", "", "", "", "", "", "", "", "", ""] self.editable = True self.enabled = True self.dropdownWidth = 'WWWWWW' self.width = 'WWWWWW' self.refresh() def onSelChange(self, selection): self.refresh() def onEditChange(self, text): pass def onFocus(self, focused): self.refresh() def onEnter(self): pass def refresh(self): pass
I know this is an old thread, but here is a solution that allows a combo box to be editable so that the user chosen value appears in the combo box while still making sure that the final value entered by the user exactly matches an item from the items list before the combo box fully loses focus. If the user typed any value that is a case insensitive match with any item in the items list the value will be converted to the fully case sensitive version of that item. If the user leaves the combo box after entering any value that is not a case insensitive match to any of the items in the items list the combo box value will be set back to the last valid case sensitive value the user or the addin code entered into the combo box.
class cbxAccessTable(object):
"""Implementation for Capture_Coordinate_addin.cbxAccessTable (ComboBox)"""
# initialize instance variables for a case insensitive dictionary of items and
# for the last valid value the user chose or typed that matched the items list
def __init__(self):
self.items = [u"tblTCDIActive", u"tblTCDIInactive"]
self.upperDict = {i.upper():i for i in self.items}
self.editable = True
self.enabled = True
self.dropdownWidth = 'tblTCDIInactiveWW'
self.width = 'tblTCDIInactiveWW'
self.value = self.items[0]
self.oldValue = self.value
def onSelChange(self, selection):
pass
def onEditChange(self, text):
pass
def onFocus(self, focused):
if focused == False:
if not self.value.upper() in self.upperDict:
# The value entered by the user was not a case insensitive match
# Prior to fully losing focus the combo box value is changed to the
# last valid case sensitive value the user chose or entered
self.value = self.oldValue
self.refresh()
else:
# The value entered by the user was a case insensitive match
# Prior to fully losing focus the combo box value is set to make sure
# the value exactly matches the case sensitive item in the items list
self.value = self.upperDict[self.value.upper()]
self.oldValue = self.value
self.refresh()
print("onFocus fired. focused = " + str(focused) + ". self.value = " + self.value + ". oldValue = " + self.oldValue)
pass
def onEnter(self):
pass
def refresh(self):
pass
If I want to change the items list of this class from another control, I need to not only set both the cbxAccessTable.items and cbxAccessTable.value properties, but also the cbxAccessTable.upperDict property like this:
if selection == "New Items":
cbxAccessTable.items = [u"tblTCDIActive".u"tblTCDIInactive",u"tblTCDIAll"]
cbxAccessTable.upperDict = {i.upper():i for i in cbxAccessTable.items}
cbxAccessTable.value = cbxAccessTable.items[0]
cbxAccessTable.oldValue = cbxAccessTable.value
cbxAccessTable.refresh()
elif selection == "Original Items":
cbxAccessTable.items = [u"tblTCDIActive".u"tblTCDIInactive"]
cbxAccessTable.upperDict = {i.upper():i for i in cbxAccessTable.items}
cbxAccessTable.value = cbxAccessTable.items[0]
cbxAccessTable.oldValue = cbxAccessTable.value
cbxAccessTable.refresh()