1

I'm creating an application with a ListBox. I want the user to be able to click on it, start typing, and see their text appear in that item. Below is a simplified version that almost works:

using System.Windows.Forms;

namespace ListboxTest
{
    public partial class ListboxTest : Form
    {
        InitializeComponent();
        listBox1.Items.Add("");
        listBox1.Items.Add("");
        listBox1.KeyPress += new KeyPressEventHandler(ListBoxKeyPress);
    }

    private void ListBoxKeyPress(object sender, KeyPressEventArgs e)
    {
        ListBox lbx = (ListBox)sender;
        if (lbx.SelectedIndices.Count != 1)
            return;

        int temp = lbx.SelectedIndex;
        string value = lbx.Items[temp].ToString();
        value += e.KeyChar;

        lbx.Items[temp] = value;
    }
}

When the ListBox is selected, the user can start typing and see the text show up. Everything works as expected until two things happen:

  1. User switches from one item to another (click into a different input or use the up/down arrows), followed by
  2. User presses the key corresponding to the first character in the unselected item's name.

From then on, whenever the user presses that key (in my case, a '1'), the ListBox's selected item changes. With only two items (both starting with '1'), pressing '1' causes the ListBox to switch the selected item from index 0 to index 1 (and vice-versa).

I've experimented a bit, and this is what I've found.

  • This only occurs when I press '1'. No other digit, numeral, or punctuation mark causes this. This will happen with any character that the ListBox item begins with.
  • If the ListBox has more than two items, it will cycle through all previously entered elements with the same start character. Items that have never been selected are skipped.

What I've tried:

  • Clearing the selected indices by ListBox.SetSelected(int index, bool selected)
  • Clearing the selected indices by ListBox.ClearSelected()
  • Setting Listbox.SelectionMode to SelectionMode.One

I am using VS 2015 Professional, Windows 7 SP1 (x64), C# 6.0, and targeting .NET 4.6.1.

So, my question: what's happening and how do I fix it?

Glasses2C_Sharp
  • 149
  • 2
  • 8

2 Answers2

2

If you type any keybord keys while Listbox is in focus, it actually traverse through its all items and select those items (one by one) which start with typed key. so it is basic behavior of Listbox.

you need use KeyEventArgs.SuppressKeyPress Property here, for that you will need to write your logic in such event where you get KeyEvenArgs , such as KeyDown

try following code

    private void lstBoxItems_KeyDown(object sender, KeyEventArgs e)
    {
        ListBox lbx = (ListBox)sender;
        if (lbx.SelectedIndices.Count != 1)
            return;

        e.SuppressKeyPress = true;

        //calling this method to get char from key data
        char keyChar = GetChar(e);

        int temp = lbx.SelectedIndex;
        string value = lbx.Items[temp].ToString();
        value += keyChar;

        lbx.Items[temp] = value;
    }

and add this method too

    char GetChar(KeyEventArgs e)
    {
        int keyValue = e.KeyValue;
        if (!e.Shift && keyValue >= (int)Keys.A && keyValue <= (int)Keys.Z)
            return (char)(keyValue + 32);
        return (char)keyValue;
    }

some other question I searched where you can get reference,

How to disable listbox auto select item when pressing key

I got method to convert key data to char from here.

Get the char on Control.KeyDown?

Amit
  • 1,821
  • 1
  • 17
  • 30
0

Thanks to Amit for pointing me in the right direction. This is the default behavior of ListBox. However, there's actually an easier way to suppress this behavior with the event handler I'm using.

When using the event handler "KeyPress", you can set e.Handled = true to suppress further processing. This prevents the Listbox from selecting a different item while typing.

Glasses2C_Sharp
  • 149
  • 2
  • 8