如何为Winform listview添加鼠标多选支持?

时间:2014-10-16 08:11:46

标签: c# winforms listview multi-select onmouseover

我需要为winform listview添加鼠标多选支持。 (用户将点击一个项目并将其拖动到第五个并且她将能够选择项目1到5)我认为我应该继承listview以向其添加新功能但我不知道哪些事件或我应该添加方法。我该怎么做?提前谢谢。

2 个答案:

答案 0 :(得分:1)

自定义ListView并覆盖MouseMove(红利 - Ctr + A 支持):

[System.ComponentModel.DesignerCategory("Code")]
public class MyListView : ListView
{
    protected override void OnMouseMove(MouseEventArgs e)
    {
        // easy mouse selection
        if (MouseButtons == MouseButtons.Left)
        {
            var item = this.HitTest(e.Location).Item;
            if (item != null)
                item.Selected = true;
        }
        base.OnMouseMove(e);
    }

    protected override void OnKeyDown(KeyEventArgs e)
    {
        // ctrl-a - select all
        if (e.KeyCode == Keys.A && e.Control)
            SelectAll();
        base.OnKeyDown(e);
    }
}

这不是最好的实现,如果你移动得太快,那么有些项目将被跳过。

一些解释

ListView是一个特殊的控件,因为它有不同的视图来呈现数据。在图标视图中,您可以通过使用鼠标绘制矩形来选择多个项目(按下按钮,绘制矩形,释放)。同样适用于详细信息视图。所有与矩形项相交的将被选中。重要提示:这种选择方式需要从未被项目区域开始绘制矩形。

问题:在详细信息中查看位于最后一列右侧和最后一项底部的未占用区域。通常列占据所有水平空间,项目全部垂直,因此不存在这样的区域。所以这种选择方式不起作用!

ListView中选择多个项目的其他众所周知的可能性是选择第一个项目,按 Shift 然后单击最后一个项目。将选择范围中的所有项目(或图标视图中的矩形)。或者按 Ctr 并单击项目逐个切换选择。

答案 1 :(得分:1)

Sinatrs方法是一个好主意。

使用“详细信息”视图,您可以尝试这样的操作,以获得类似行为的Windows资源管理器:

    Int32 firstClickItemIndex = 0;

    public Boolean numInRange(Int32 num, Int32 first, Int32 last)
    {
        return first <= num && num <= last;
    }       

    private void listView1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.A && e.Control)
        {
            foreach (ListViewItem lvItem in listView1.Items)
                lvItem.Selected = true;
        }
    }

    private void listView1_MouseDown(object sender, MouseEventArgs e)
    {
        if (MouseButtons == MouseButtons.Left && listView1.HitTest(e.Location).Item != null)
            firstClickItemIndex = listView1.HitTest(e.Location).Item.Index;            
    }

    private void listView1_MouseMove(object sender, MouseEventArgs e)
    {
        if (MouseButtons == MouseButtons.Left)
        {
            ListViewItem lvItem = listView1.HitTest(e.Location).Item;
            if (lvItem != null)
            {
                lvItem.Selected = true;
                if (listView1.SelectedItems.Count > 1)
                {
                    Int32 firstSelected = listView1.SelectedItems[0].Index;
                    Int32 lastSelected = listView1.SelectedItems[listView1.SelectedItems.Count - 1].Index;
                    foreach (ListViewItem tempLvItem in listView1.Items)
                    {
                        if (numInRange(tempLvItem.Index, firstSelected, lastSelected) && (numInRange(tempLvItem.Index, lvItem.Index, firstClickItemIndex) || numInRange(tempLvItem.Index, firstClickItemIndex, lvItem.Index)))
                        {
                            tempLvItem.Selected = true;
                        }
                        else
                        {
                            tempLvItem.Selected = false;
                        }
                    }
                }
            }
        }
    }