将选择所有快捷方式(Ctrl + A)添加到.net列表视图?

时间:2009-06-19 18:24:04

标签: c# .net listview keyboard-shortcuts

就像主题说我有一个listview,我想添加 Ctrl + A 选择它的所有快捷方式。我的第一个问题是我无法弄清楚如何以编程方式选择列表视图中的所有项目。它似乎应该相对容易,例如ListView.SelectAll()ListView.Items.SelectAll(),但似乎并非如此。我的下一个问题是如何定义ListView的键盘快捷键。我是在KeyUp事件中进行的,但是如何一次检查两次按下?或者它是你设置的属性?

这里的任何帮助都会很棒。

5 个答案:

答案 0 :(得分:31)

你可以用这样的东西来完成两件事:

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

答案 1 :(得分:23)

这些适用于小型列表,但如果虚拟列表中有100,000个项目,则可能需要很长时间。这对你的目的来说可能有点过头了,但仅限于以下情况::

class NativeMethods {
    private const int LVM_FIRST = 0x1000;
    private const int LVM_SETITEMSTATE = LVM_FIRST + 43;

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct LVITEM
    {
        public int mask;
        public int iItem;
        public int iSubItem;
        public int state;
        public int stateMask;
        [MarshalAs(UnmanagedType.LPTStr)]
        public string pszText;
        public int cchTextMax;
        public int iImage;
        public IntPtr lParam;
        public int iIndent;
        public int iGroupId;
        public int cColumns;
        public IntPtr puColumns;
    };

    [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
    public static extern IntPtr SendMessageLVItem(IntPtr hWnd, int msg, int wParam, ref LVITEM lvi);

    /// <summary>
    /// Select all rows on the given listview
    /// </summary>
    /// <param name="list">The listview whose items are to be selected</param>
    public static void SelectAllItems(ListView list) {
        NativeMethods.SetItemState(list, -1, 2, 2);
    }

    /// <summary>
    /// Deselect all rows on the given listview
    /// </summary>
    /// <param name="list">The listview whose items are to be deselected</param>
    public static void DeselectAllItems(ListView list) {
        NativeMethods.SetItemState(list, -1, 2, 0);
    }

    /// <summary>
    /// Set the item state on the given item
    /// </summary>
    /// <param name="list">The listview whose item's state is to be changed</param>
    /// <param name="itemIndex">The index of the item to be changed</param>
    /// <param name="mask">Which bits of the value are to be set?</param>
    /// <param name="value">The value to be set</param>
    public static void SetItemState(ListView list, int itemIndex, int mask, int value) {
        LVITEM lvItem = new LVITEM();
        lvItem.stateMask = mask;
        lvItem.state = value;
        SendMessageLVItem(list.Handle, LVM_SETITEMSTATE, itemIndex, ref lvItem);
    }
}

你可以像这样使用它::

NativeMethods.SelectAllItems(this.myListView);

答案 2 :(得分:5)

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

在Ctrl + A上执行,而不是在Ctrl + Shift + A等其他组合上执行。

答案 3 :(得分:3)

如果用户首先释放 Ctrl 键,则第一个解决方案将无效。

您应该使用KeyDown事件:

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

答案 4 :(得分:0)

我无法评论第一个问题,但使用KeyDown的解决方案对我不起作用,因为系统会立即对LeftCtrl做出反应,因此会跳过CTRL + A.从另一侧KeyUp正常工作。

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