【问题标题】:Listbox cycling through items when '1' is pressed按下“1”时列表框循环显示项目
【发布时间】:2018-05-22 02:13:35
【问题描述】:

我正在使用 ListBox 创建一个应用程序。我希望用户能够单击它,开始输入,并看到他们的文本出现在该项目中。下面是一个几乎可以工作的简化版本:

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;
    }
}

选择 ListBox 后,用户可以开始输入并看到显示的文本。一切都按预期进行,直到发生两件事:

  1. 用户从一项切换到另一项(点击不同的输入或使用向上/向下箭头),然后是
  2. 用户按下与未选择项目名称中的第一个字符对应的键。

从那时起,每当用户按下该键(在我的例子中为“1”)时,ListBox 的选定项都会更改。只有两个项目 (都以 '1' 开头),按 '1' 会导致 ListBox 将所选项目从索引 0 切换到索引 1(反之亦然)。

我做了一些实验,这就是我发现的。

  • 这仅在我按“1”时发生。没有其他数字、数字或标点符号会导致此问题。 ListBox 项开头的任何字符都会发生这种情况。
  • 如果 ListBox 有两个以上的项目,它将循环遍历所有先前输入的具有相同起始字符的元素。从未选择过的项目将被跳过。

我尝试过的:

  • 通过ListBox.SetSelected(int index, bool selected) 清除选定的索引
  • 通过ListBox.ClearSelected() 清除选定的索引
  • Listbox.SelectionMode 设置为SelectionMode.One

我正在使用 VS 2015 Professional、Windows 7 SP1 (x64)、C# 6.0,并针对 .NET 4.6.1。

那么,我的问题是:发生了什么,我该如何解决?

【问题讨论】:

  • 你的意思是,在打字的时候用户将能够看到他输入的项目正在被输入到列表视图中?
  • @mjwills 在这种情况下,对不起。你继续!
  • @mjwills:它是“1”。
  • @Amit 是的。那部分工作正常。我担心每次用户按“1”时都会更改所选项目。

标签: c# winforms listbox


【解决方案1】:

如果您在 Listbox 处于焦点时键入任何键盘键,它实际上会遍历其所有项目并选择那些以键入的键开头的项目(一个接一个)。所以这是Listbox的基本行为。

您需要在这里使用KeyEventArgs.SuppressKeyPress 属性,因为您需要在获得KeyEvenArgs 的情况下编写逻辑,例如KeyDown

试试下面的代码

    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;
    }

并添加此方法

    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;
    }

我搜索了一些其他问题,您可以在哪里获得参考,

How to disable listbox auto select item when pressing key

我得到了从这里将关键数据转换为字符的方法。

Get the char on Control.KeyDown?

【讨论】:

    【解决方案2】:

    感谢 Amit 为我指明了正确的方向。这是 ListBox 的默认行为。但是,实际上有一种更简单的方法可以使用我正在使用的事件处理程序来抑制这种行为。

    使用事件处理程序“KeyPress”时,您可以设置 e.Handled = truesuppress further processing。这可以防止列表框在键入时选择不同的项目。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多