== Introduction == This recipe offers a `wxComboBox` subclass that will display the first entire item from its dropdown list whose initial characters match those that the user has typed, with untyped characters selected. == What Objects are Involved == Only `wx.ComboBox` itself. == Process Overview == When the user keys a 'c', for instance, we want the code to identify the first combobox choice that begins with 'c', and to display it in the combobox with the characters following 'c' "selected". One does this in response to the wx.EVT_TEXT event. When one changes the content of the combobox, however, this ellicits another wx.EVT_TEXT event and this leads to infinite recursion. To prevent this we arrange to ignore the second wx.EVT_TEXT that is ellicited. Similar code is used to make it possible for the control to respond properly to backspaces, and when the user selects a choice from the dropdown list. == Special Concerns == The code in the loop in the wx.EVT_TEXT handler might well be changed so that the combobox would accept plugins providing different suggestion options; for example, the most frequently selected option could be offered. == Code Sample == {{{ #!python import wx class PromptingComboBox(wx.ComboBox) : def __init__(self, parent, value, choices=[], style=0, **par): wx.ComboBox.__init__(self, parent, wx.ID_ANY, value, style=style|wx.CB_DROPDOWN, choices=choices, **par) self.choices = choices self.Bind(wx.EVT_TEXT, self.EvtText) self.Bind(wx.EVT_CHAR, self.EvtChar) self.Bind(wx.EVT_COMBOBOX, self.EvtCombobox) self.ignoreEvtText = False def EvtCombobox(self, event): self.ignoreEvtText = True event.Skip() def EvtChar(self, event): if event.GetKeyCode() == 8: self.ignoreEvtText = True event.Skip() def EvtText(self, event): if self.ignoreEvtText: self.ignoreEvtText = False return currentText = event.GetString() found = False for choice in self.choices : if choice.startswith(currentText): self.ignoreEvtText = True self.SetValue(choice) self.SetInsertionPoint(len(currentText)) self.SetMark(len(currentText), len(choice)) found = True break if not found: event.Skip() class TrialPanel(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent, wx.ID_ANY) choices = ['grandmother', 'grandfather', 'cousin', 'aunt', 'uncle', 'grandson', 'granddaughter'] for relative in ['mother', 'father', 'sister', 'brother', 'daughter', 'son']: choices.extend(self.derivedRelatives(relative)) cb = PromptingComboBox(self, "default value", choices, style=wx.CB_SORT) def derivedRelatives(self, relative): return [relative, 'step' + relative, relative + '-in-law'] if __name__ == '__main__': app = wx.App() frame = wx.Frame (None, -1, 'Demo PromptingComboBox Control', size=(400, 50)) TrialPanel(frame) frame.Show() app.MainLoop() }}} === Comments === Any comments or suggestions, to [[Bill Bell]], please.