C#列表框项双击事件

63

我有一个列表框,其中包含一些项目。有没有办法为每个项目附加双击事件?

Item 1
Item 2
Item 3
如果我双击Item 2,那么会弹出一个显示"Item 2"的MessageBox。如何实现这个功能?
7个回答

137
void listBox1_MouseDoubleClick(object sender, MouseEventArgs e)
{
    int index = this.listBox1.IndexFromPoint(e.Location);
    if (index != System.Windows.Forms.ListBox.NoMatches)
    {
        MessageBox.Show(index.ToString());
    }
}

这应该可以运行... 检查一下


5
"e.Location"是什么???你确定有这个方法吗?在Visual Studio里按Ctrl+空格也没出现这个方法建议。 - Milad Sobhkhiz
9
@Milas: 我也遇到了同样的问题。请确保您使用的是MouseDoubleClick事件(因此是MouseEventArgs),而不是DoubleClick事件(该事件仅有EventArgs)。 - winwaed
1
为什么不使用 SelectedItem - Jack
4
当用户在列表框的空白区域进行点击时,SelectedItem 可能不为 null - Haoshu
1
IndexFromPoint 是什么? - PreguntonCojoneroCabrón
显示剩余3条评论

32

WinForms

为您的ListBox添加Control.DoubleClick事件处理程序,在该事件处理程序中打开一个MessageBox,显示所选项目。

E.g.:

 private void ListBox1_DoubleClick(object sender, EventArgs e)
 {
     if (ListBox1.SelectedItem != null)
     {
         MessageBox.Show(ListBox1.SelectedItem.ToString());
     }
 }

这里的 ListBox1 是你的 ListBox 的名称。

请注意,你可以像这样分配事件处理程序:

ListBox1.DoubleClick += new EventHandler(ListBox1_DoubleClick);

WPF
基本上与上面相同,但您需要使用MouseDoubleClick事件

ListBox1.MouseDoubleClick += new RoutedEventHandler(ListBox1_MouseDoubleClick);

还有事件处理程序:

 private void ListBox1_MouseDoubleClick(object sender, RoutedEventArgs e)
 {
     if (ListBox1.SelectedItem != null)
     {
         MessageBox.Show(ListBox1.SelectedItem.ToString());
     }
 }

编辑:Sisya的回答检查双击是否发生在项目上,需要将其合并到此代码中以解决评论中提到的问题(如果在选择项目时双击ListBox,但未单击项目,则显示MessageBox)。
希望这可以帮助!

8
嘿,我刚试了一下,它确实有效...但是如果我选择一个项目,然后双击列表框的空白部分,事件仍然会触发并显示消息框,因为即使我没有双击它,该项目仍然被选中...有什么想法? :/ - Ozzy
我尝试过这个,不得不使用新的MouseButtonEventHandler(ListBox1_NouseDoubleClick);才能在WPF上正常工作。 - Jiminion

16

我知道这个问题很老了,但我也在寻找解决这个问题的方法。 接受的解决方案是针对 WinForms 而不是 WPF,我认为许多来到这里的人都在寻找 WPF 的解决方案。

对于任何寻找 WPF 解决方案的人,这里有一个很好的方法(来自 Oskar 在这里的回答):

private void myListBox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
    DependencyObject obj = (DependencyObject)e.OriginalSource;

    while (obj != null && obj != myListBox)
    {
        if (obj.GetType() == typeof(ListBoxItem))
        {
             // Do something
             break;
         }
         obj = VisualTreeHelper.GetParent(obj);
    }
}

基本上,您需要沿着 VisualTree 向上走,直到找到一个父项是 ListBoxItem,或者您上升到实际的 ListBox(因此没有单击 ListBoxItem)。


这似乎是WPF中给出的最佳解决方案,但我如何仅获取所单击项目的文本?例如,如果我执行obj.ToString(),我会得到“System.Windows.Controls.ListBoxItem:myItem”,那么我该如何只获取myItem?我尝试了几种不同的方法来访问它,但我得到的与obj.ToString()相同。我知道我可以解析字符串(obj.ToString().Split(' ')[1]),但我想知道是否有更简洁的解决方案。 - Chris

9

针对Winforms

private void listBox1_DoubleClick(object sender, MouseEventArgs e)
    {
        int index = this.listBox1.IndexFromPoint(e.Location);
        if (index != System.Windows.Forms.ListBox.NoMatches)
        {
            MessageBox.Show(listBox1.SelectedItem.ToString());
        }
    }

and

public Form()
{
    InitializeComponent();
    listBox1.MouseDoubleClick += new MouseEventHandler(listBox1_DoubleClick);
}

如果您选择一个项目,然后单击空白区域,这也应该防止事件触发。


2
这取决于您使用的是 System.Windows.Forms.ListBox 类的 ListBox 对象,该类具有 ListBox.IndexFromPoint() 方法。但如果 ListBox 对象来自 System.Windows.Control.Listbox 类,则 @dark-knight 的答案(标记为正确答案)不起作用。
我正在运行 Win 10 (1903) 和当前版本的 .NET framework (4.8)。这个问题不应该与版本有关,只与应用程序是使用 WPF 还是 Windows Form 进行 UI 有关。 参见:WPF vs Windows Form

添加操作系统和当前软件版本。(来自审核) - ZF007
操作系统:Win 10 1903,我不确定这个答案需要哪个软件版本? - Tanque
我希望现在没问题了?实际上,我本来想将这个答案作为对@dark-knight标记答案的回复添加进去,但是它不让我这样做。 - Tanque

1

这是一篇很旧的文章,但如果有人遇到类似问题并需要快速答案:

  • 使用MouseDown事件来捕获ListBox项的点击。
  • 要捕获点击的项而不是列表框中的空白处,请检查listBox1.IndexFromPoint(new Point(e.X,e.Y))>=0
  • 要捕获双击事件,请检查e.Clicks == 2

0

这篇文章可能有点老了,但对于那些需要它的人来说,有一个简单的解决方案。

private void listBox1_DoubleClick(object sender, EventArgs e)
{
   if (listBox1.SelectedIndex > -1)
   {
      MessageBox.Show(listBox1.Items[listBox1.SelectedIndex].ToString());
   }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接