【问题标题】:WinForms listbox keydown event won't fireWinForms 列表框 keydown 事件不会触发
【发布时间】:2017-03-31 20:21:31
【问题描述】:

我正在尝试制作一个 WinForm ListBox,您可以在其中使用箭头键循环。我还有两个按钮,您可以单击它们在列表中上下移动。这些按钮确实产生了预期的效果。问题是 ListBox 的 keyDown 事件永远不会被触发

    public MainForm()
    {
        InitializeComponent();
        if (this.clipboardHistoryList.Items.Count > 0)
            this.clipboardHistoryList.SetSelected(0, true);
        clipboardHistoryList.Select();
    }

   private void goUpButton_Click(object sender, EventArgs e)
    {
        goUpList();
    }

    private void goDownButton_Click(object sender, EventArgs e)
    {
        goDownList();
    }

    private void goDownList()
    {
        if (clipboardHistoryList.SelectedIndex == clipboardHistoryList.Items.Count - 1)
        {
            clipboardHistoryList.SetSelected(0, true);
        }
        else
        {
            clipboardHistoryList.SetSelected(clipboardHistoryList.SelectedIndex + 1, true);
        }
    }

    private void goUpList()
    {
        if (clipboardHistoryList.SelectedIndex == 0)
        {
            clipboardHistoryList.SetSelected(clipboardHistoryList.Items.Count - 1, true);
        }
        else
        {
            int l_currentlySelected = clipboardHistoryList.SelectedIndex;
            clipboardHistoryList.SetSelected(l_currentlySelected - 1, true);
        }
    }

    private void clipboardHistoryList_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Up)         //Brekpoint is never reached
        {
            goUpList();
        }
        else if (e.KeyCode == Keys.Down)
        {
            goDownList();
        }
    }

我已将 MainForm 的 keypreview 属性设置为 true。

默认情况下,箭头键在列表框上确实有效,但如果您按最后一个元素上的向下箭头,它们不会让您从最后一个元素转到第一个元素——希望这是有道理的。

编辑 我在Microsoft's documentation 上看到我需要重写ProcessDialogKey 方法,但我不确定我需要做什么。

对控件执行特殊输入或导航处理。例如,您希望使用列表控件中的箭头键来更改所选项目。覆盖 ProcessDialogKey

是否已经有一种内置方法可以启用此行为?

我错过了什么?

谢谢!

【问题讨论】:

  • 您是否 100% 确定您的 ListBox 实际上已连接到您的事件处理程序?当我创建一个带有 ListBox 的表单时,每次使用箭头键时它都会正确触发 KeyDown 事件。我建议查看您的表单的 Designer.cs 文件,并验证您是否可以找到与此类似的行,它实际上连接到事件中:this.listBox1.KeyDown += new System.Windows.Forms.KeyEventHandler( this.listBox1_KeyDown);
  • ListBox 要么没有焦点,要么你没有连接事件。 I have put the MainForm's keydown proprety to true. 你是说 KeyPreview 吗?
  • @JoeIrby 我在我的 Form1.Designer.cs 文件中看不到任何类似的行。我用这个文件的内容更新了问题。
  • @LarsTech 我的意思是keypreview
  • 你必须连接你的事件。请注意您的按钮如何在设计器中连接事件,但您的 ListBox 没有。

标签: c# winforms listbox keydown eventtrigger


【解决方案1】:

从您的 Designer.cs 文件中的代码来看,您实际上并没有将您的 clipboardHistoryList 控件连接到您的 clipboardHistoryList_KeyDown 事件处理程序中。您可以通过 Visual Studio 表单设计器中“属性”窗口的“事件”子选项卡执行此操作(查找小闪电图标),然后通过该设计器连接事件,或者您可以在代码中执行此操作:

public MainForm()
{
    InitializeComponent();
    if (this.clipboardHistoryList.Items.Count > 0)
        this.clipboardHistoryList.SetSelected(0, true);
    clipboardHistoryList.Select();

    clipboardHistoryList.KeyDown += clipboardHistoryList_KeyDown;
}

【讨论】:

  • 谢谢你,现在事件被正确触发了!但是我现在面临另一个问题......每次按下箭头时,光标都会移动两行,就好像 keydown 事件是由我的方法和默认组件的方法处理的一样。我该如何解决这个问题?
  • 需要加上e.handled = true;到您的新事件处理程序。
  • 非常感谢,已解决!
  • @Gaboik1 实际上可能会意外地将事件连接到两次,在这种情况下,每次都会被调用两次,正如您所经历的那样。如果您将我的代码行添加到 MainForm() 构造函数中,AND 您还通过设计器连接到事件中,那么这可能就是发生的情况。你只需要做一个或另一个(你的选择),而不是两者。
  • @JoeIrby 嗯,这很有趣,因为我只是将它连接到 Designer 文件中,它仍然被调用了两次。将事件的处理属性设置为 true 解决了它
猜你喜欢
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-29
相关资源
最近更新 更多