Programming a ComboBox that appends selected items to its textbox
This is a problem I've had to deal with in my last project, and although I found a working solution, I wasn't too happy with it and am wondering if there would've been a better, cleaner one.
Problem:
Basically, I needed to implement a ComboBox that inserts or appends an item (selected from the drop-down list) to the textbox instead of replacing all text in the textbox:
- If the textbox has some text selected, that selection would be replaced with an item selected from the drop-down list;
- If the textbox has no text selected, an item chosen from the drop-down list would be appended in the textbox field.
As it turned out, I could not achieve this behaviour by handling a combination of ComboBox
's events (s开发者_高级运维uch as SelectedIndexChanged
, SelectionChangeCommitted
, TextChanged
etc.) because the ComboBox
control would finally synchronize the textbox field with the selected item from the drop-down list without raising any further events afterwards.
Solution, a.k.a ugly hack:
I ended up installing a Timer
that, once expired, causes an update to the textbox field. The timer was set to approx. 30 ms, which should be long enough to ensure that all events (SelectedIndexChanged
, TextUpdate
etc.) have been processed, and short enough to not feel like a noticeable lag to the user.
Does anyone know of a cleaner solution to this problem?
I'm sure you already know this, but I repeat it here to make you think consider the implications. A combo box is a relatively sophisticated control that is made of of simpler components interacting in a pre-defined way. A textbox, a list box and a button combine to create a control designed to simplify a common method of providing a compact UI for simplified text input and selection.
It seems your case does not lend itself to the pre-defined interactions of these components the way a combo box has designed them. Therefore my suggestion would be to separately create the textbox, listbox and button and manually define how they interact rather than trying to fight the pre-defined behavior of the combo box.
What you want is not a ComboBox. You want a text box and a button that when clicked gives you a drop down list of tokens which can be inserted into the text box. A ComboBox nearly gives you this but is unsuitable for two reasons:
- Users known how ComboBoxes work. Your component looks like a ComboBox but doesn't behave like one. That will just cause confusion.
- ComboBoxes are designed in the way they are so that users will always know how they work and can be familiar with them. It is not the intention that the selected item differs from the text. You can't override this behaviour because if you did, it would no longer be a ComboBox as we know it. Trying to override it to completely change the behavior of the control in a way for which it was not designed causes problems that are not easy to fix.
You should write a custom control which implements the features you need and has a UI that better represents what you are doing. To look for inspiration you could consider the 'insert emoticon' UI that many instant messaging programs have. Notice that the button is not typically inside the text box but a completely separate button.
精彩评论