在ListView中双击一行

21

有没有可能在ListView中获取双击行的值? 我注册了一个事件:

    private void lvLista_DoubleClick(object sender, EventArgs e)
    {
        MessageBox.Show(lvLista.SelectedItems.ToString());
    }

但是在消息中,当我双击列表视图中的某一行时,会出现以下内容:

System.Windows.Forms.ListView+SelectedListViewItemCollection

此外,我的列表视图中有两列:

    lvLista.Columns.Add("ID");
    lvLista.Columns.Add("Tilte");

我想在消息框中显示双击行的“ID”。


如何做到?如何从此事件中获取值?

6个回答

30
如果您处理了ListView控件的MouseDown和/或MouseDoubleClick事件,并使用HitTest方法确定鼠标操作的目标,则会知道已经双击了哪个项。这也是确定是否未单击任何项(例如,在部分填充列表中单击空白区域)的好方法。
如果发生单击,则以下代码将在文本框中显示所单击的项;如果发生双击,则弹出一条消息框,显示双击的项的名称。如果单击或双击在未由项目填充的列表视图区域发生,则文本框或消息框会通知您这个事实。
这是一个微不足道的例子,根据您的需要,您将不得不稍微调整它。
更新:我添加了一些代码,当单击或双击列表的空白区域时,清除了Listview控件的SelectedItems属性。
public partial class Form1 : Form
{

    public Form1()
    {
        InitializeComponent();

        listView1.MouseDown += new MouseEventHandler(listView1_MouseDown);
        listView1.MouseDoubleClick += new MouseEventHandler(listView1_MouseDoubleClick);
        this.Load += new EventHandler(Form1_Load);
    }


    void Form1_Load(object sender, EventArgs e)
    {
        this.SetupListview();
    }


    private void SetupListview()
    {
        ListView lv = this.listView1;
        lv.View = View.List;


        lv.Items.Add("John Lennon");
        lv.Items.Add("Paul McCartney");
        lv.Items.Add("George Harrison");
        lv.Items.Add("Richard Starkey");
    }


    void listView1_MouseDoubleClick(object sender, MouseEventArgs e)
    {
        ListViewHitTestInfo info = listView1.HitTest(e.X, e.Y);
        ListViewItem item = info.Item;

        if (item != null)
        {
            MessageBox.Show("The selected Item Name is: " + item.Text);
        }
        else
        {
            this.listView1.SelectedItems.Clear();
            MessageBox.Show("No Item is selected");
        }
    }



    void listView1_MouseDown(object sender, MouseEventArgs e)
    {
        ListViewHitTestInfo info = listView1.HitTest(e.X, e.Y);
        ListViewItem item = info.Item;

        if (item != null)
        {
            this.textBox1.Text = item.Text;
        }
        else
        {
            this.listView1.SelectedItems.Clear();
            this.textBox1.Text = "No Item is Selected";
        }
    }
}

23

试试这个:

private void lvLista_DoubleClick(object sender, EventArgs e)
{

    MessageBox.Show(lvLista.SelectedItems[0].SubItems[0].Text);
}

3
这段代码可能存在问题,如果用户在列表的空白区域单击或双击会发生什么?在某些情况下,他们可能希望上一次选择的项目成为结果。然而,在其他情况下,除非用户明确选择了一个项目进行双击,否则可能希望不发生任何操作。 - XIVSolutions
1
我发现我之前的理解至少有一点错误。如果用户双击空白区域,DoubleClick事件不会触发。这是我的短视(我一直在使用另一种实现方式,它设置了一个成员变量供其他方法使用,因此必须使用MouseDown事件来处理未单击任何内容的情况)。 - XIVSolutions
1
当您双击行上的复选框时,此代码存在问题。 - confusedMind
将ListViewHitTestInfo info = listView1.HitTest(e.X, e.Y);的解决方案与这个解决方案结合起来是我的做法。 - undefined

9

我知道这个帖子已经很老了,但在我看来,这里没有人正确回答了这个问题。对于未来的读者,可以尝试以下方法,来源于MSDN

// User must double-click to activate item
myListView.Activation = System.Windows.Forms.ItemActivation.Standard;

// Add event handler
myListView.ItemActivate += new 
System.EventHandler(this.myListView_ItemClick);

4
虽然这适用于双击,但如果物品被两次非常明显的单击,则事件也会触发。 - Jerther
我认为这是最好的解决方案。 - elle0087
1
将激活设置为“TwoClick”允许两次不同的点击,但“Standard”只允许双击。我已更新答案以使用“Standard”。 - tronman

3

由于已接受的答案对我没有帮助,所以我想分享我的解决方案,即在双击事件中获取列表视图中特定列的数据。

以下行返回我双击的行中第二列的数据作为字符串:

private void listViewOutput_DoubleClick(object sender, EventArgs e)
{
   string content = listViewOutput.Items[listViewOutput.SelectedIndices[0]].SubItems[1].Text
}

2

试一下这个

private void listView1_MouseClick(object sender, MouseEventArgs e)
{
    ListViewHitTestInfo hit = listView1.HitTest(e.Location);

    Rectangle rowBounds = hit.SubItem.Bounds;
    Rectangle labelBounds = hit.Item.GetBounds(ItemBoundsPortion.Label);
    int leftMargin = labelBounds.Left - 1;

    string x = hit.Item.Text;

}

2

谢谢,这正是我需要的。我想提一下,可以将本地信息变量更普遍地设置为:

  ListViewHitTestInfo info = ((ListView)sender).HitTest(e.X, e.Y);

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