Introduction
This article is an elementary tutorial that shows you how you can have
auto-completing combo-boxes in your Managed C++ programs. Of course it
wouldn't be much of a difficulty to convert the code straight to C# or VB .NET.
The technique described in this article requires you to have the final release
of VS.NET. It will not work on any beta version of VS.NET including beta 2 as
I found out after two days of frustration.
Screenshots
The above screenshot shows how it works for a drop down combo box.
This screenshot shows how it works for a simple combo box
Description
Basically what we do here is to derive a class from the ComboBox
class. Then we override the OnKeyPress
method that is called when a key
is pressed. For certain keys we would like to call the base class handler. These
keys are the BackSpace key which has some expected behaviour and it would not be
polite of our class to mess with expected behaviour. Other keys that have
pre-defined roles include the cursor keys. We also need to check the ComboBox
style. If it is a drop-list combo box where the edit box is uneditable, we
should not do anything funny, and instead should simply call the base class
function.
if(e->KeyChar == Windows::Forms::Keys::Back ||
e->KeyChar == Windows::Forms::Keys::Up ||
e->KeyChar == Windows::Forms::Keys::Down ||
e->KeyChar == Windows::Forms::Keys::Right ||
e->KeyChar == Windows::Forms::Keys::Left ||
DropDownStyle == ComboBoxStyle::DropDownList )
{
ComboBox::OnKeyPress(e);
}
Okay. So we know when to call the base class. Now for all other cases what we
need to do is simple. Take the existing text from the edit box. Search the combo
box for an entry that starts with this text. Now we need to set the text in the
combo box to this searched and found text, except that all portions of this new
text that exceeds the old text should be selected. Thus the user can type any
key he wants to and remove all the selected text. That's what
auto-completing combo boxes are supposed to do. I have written a simple search
function called FirstMatch
which takes a string and returns a string.
If our search was successful we can actually drop down our combo box and the
advantage is that the selection bar will automatically move to the closest match
to what's in the edit box. In our case there will be an exact match of course. I
was wondering how to get this effect and it was very pleasing to get it free of
effort. But we must remember to check to see if the combo box has the DropDown
style set. If it is a simple combo box we don't want to try dropping it down.
String *str = FirstMatch(Text);
if(str->Length)
{
int q1 = Text->Length;
int q2 = str->Length - Text->Length;
Text = str;
if(DropDownStyle == ComboBoxStyle::DropDown)
DroppedDown = true;
SelectionStart = q1;
SelectionLength = q2;
}
else
{
if(DropDownStyle == ComboBoxStyle::DropDown)
DroppedDown = false;
}
Finally we need to inform Windows that the event has been handled. For this
we need to set the Handled
property of the KeyPressEventArgs
object passed to us to true
. If we don't set this to true
, this message will be
send for default processing. Since we've handled it already, there is no need
for that.
e->Handled = true;
Conclusion
I've noticed that when you take Run from the Start Menu, there is an
auto-completing combo box. But there is a difference there in that the dropped
down list is resizable. I haven't figured out how to do that unfortunately and
I'd much appreciate it if anyone could give me some pointers. I hope it won't
involve any of that owner draw stuff!