I have previously asked a question on how to Selecting dynamically created Listboxs items in C# which was answered. The problem now is that when the listbox gets the focus when popped up! I can't continue typing unless I either select an item or press Esc, which I have explicitly defined to set focus back to my TextBox
.
The irony is that I have a condition in my KeyDown
event which says if the UP or Down arrow keys are pressed, set the focus on ListBox
so that user can choose an item, but don't transfer the focus so that user can continue typing freely.
Just like what we have on Visual Studio, when a user presses a dot, he is not blocked and forced to choose an item form the Intellisense list, but he can continue typing and or at any time use arrow keys UP or Down to select the proper item.
I can't achieve the same functionality using the code below. How can I get this to work as mentioned?
I need to say that using ActiveControl, and transferFocus, using this.Focus()
prior to lst.Focus()
, disabling and enabling textbox they all didn't work!
private void txtResults_KeyDown(object sender, KeyEventArgs e)
{
string[] words= ((TextBox)sender).Text.Split(' ');
string s = sampleWord.Text = words[words.Length - 1];
if (e.KeyCode == Keys.OemPeriod)
{
ShowPopUpList(s);
lst.Focus(); //This transfers the focus to listbox but then prevents user
//from being able to type anymore unless he/she chooses an item!
}
else if (e.KeyCode == Keys.Down || e.KeyCode == Keys.Up)
{
lst.Focus();//doesnt work :-/
}
else
{
lst.Hide();
txtResults.Focus();
}
}
This behavior is happening because you are shifting focus to the listbox. Try thinking about it differently and instead of giving focus to the listbox, select the next/previous item in the list when the up or down arrows are pressed.
change your "else if" to the following:
else if (e.KeyCode == Keys.Down)
{
if (lst.SelectedIndex + 1 < lst.Items.Count)
{
lst.SelectedIndex += 1;
}
e.Handled = true;
}
else if (e.KeyCode == Keys.Up)
{
if (lst.SelectedIndex - 1 >= 0)
{
lst.SelectedIndex -= 1;
}
e.Handled = true;
}
If you want the user to be able to continue typing in the textbox while still manipulating the selection of the listbox, then you will have to fake it: don't actually set focus to the listbox when you show it. Instead, change the selection of the listbox manually in the KeyDown
event for the textbox. Something like this:
private void txtResults_KeyDown(object sender, KeyEventArgs e)
{
string[] words = ((TextBox)sender).Text.Split(' ');
string s = sampleWord.Text = words[words.Length - 1];
if (e.KeyCode == Keys.OemPeriod)
{
ShowPopUpList(s);
lst.SelectedIndex = 0;
}
else if (lst.Visible && e.KeyCode == Keys.Up)
{
// manipulate the selection on the listbox (move up)
if (lst.SelectedIndex > 0)
lst.SelectedIndex -= 1;
// eat the keypress so it textbox doesn't get it and move the cursor
e.Handled = true;
}
else if (lst.Visible && e.KeyCode == Keys.Down)
{
// manipulate the selection on the listbox (move down)
if (lst.SelectedIndex < lst.Items.Count - 1)
lst.SelectedIndex += 1;
// eat the keypress so it textbox doesn't get it and move the cursor
e.Handled = true;
}
else if (lst.Visible && e.KeyCode == Keys.Enter)
{
// insert current list box selection into text box and hide the list
txtResults.Text += lst.SelectedItem;
txtResults.SelectionStart = txtResults.Text.Length;
lst.Hide();
// eat the keypress to prevent the textbox (and the form) from acting on it
e.SuppressKeyPress = true;
e.Handled = true;
}
else
{
lst.Hide();
}
}
You don't need to focus your ListBox
to allow your user to select its item using Arrow keys
, your TextBox
should always be focused, You have to process the Enter
right in the KeyDown
event handler of your TextBox
, add the selected item there not in the KeyDown
event handler of your ListBox
, something like this:
private void txtResults_KeyDown(object sender, KeyEventArgs e)
{
string[] words= ((TextBox)sender).Text.Split(' ');
string s = sampleWord.Text = words[words.Length - 1];
if (e.KeyCode == Keys.OemPeriod)
{
ShowPopUpList(s);//Show your ListBox without needing to focus it.
}
if(lst.Visible){
if(e.KeyCode == Keys.Down){
lst.SelectedIndex = (lst.SelectedIndex + 1) % lst.Items.Count;
}
else if (e.KeyCode == Keys.Up){
lst.SelectedIndex = lst.SelectedIndex == 0 ? lst.Items.Count - 1 : lst.SelectedIndex - 1
}
else if (e.KeyCode == Keys.Enter){//Add the selected Item
//Add the selected Item here not in the KeyDown event handler of your ListBox
//.........
//.........
//Your TextBox may not need to handle the Enter, so just suppress it after adding the selected item
e.Handled = true;
}
else
{
lst.Hide();
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With