【问题标题】:Adding a select all shortcut (Ctrl + A) to a .net listview?将全选快捷方式(Ctrl + A)添加到.net listview?
【发布时间】:2009-06-19 18:24:03
【问题描述】:

就像主题说我有一个列表视图,我想添加 Ctrl + A 选择所有快捷方式。我的第一个问题是我无法弄清楚如何以编程方式选择列表视图中的所有项目。似乎它应该相对容易,例如ListView.SelectAll()ListView.Items.SelectAll(),但似乎并非如此。我的下一个问题是如何为ListView 定义键盘快捷键。我是否在KeyUp 事件中执行此操作,但是您将如何同时检查两台印刷机?还是您设置的属性?

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

【问题讨论】:

    标签: c# .net listview keyboard-shortcuts


    【解决方案1】:

    你可以用这样的方式来完成这两者:

    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;
            }
        }
    }
    

    【讨论】:

    • 哈,我知道这将是一件非常简单的事情。谢谢。
    • 我在使用 CTRL+A 时遇到问题,列表框会在全选后跳转到第一个“A”项。 (只选择一项。)在循环解决此问题后添加e.SuppressKeyPress = true;
    • 对于大型列表,应该暂停更新。 stackoverflow.com/q/15398091/340790
    • 在 2022 年使用 VS2022 这仍然有效。谢谢!
    【解决方案2】:

    这些适用于小型列表,但如果虚拟列表中有 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);
    

    【讨论】:

    • 运行此代码是否有任何先决条件?我正在使用 CheckBoxes = true 的常规 .NET ListView 上进行尝试。它什么也没做。
    • 能否提供vb.net版本
    • 非常感谢,这很好用!我在虚拟模式下使用列表视图。但不知何故,项目的数量似乎是有限的。你确定 100.000 行是可能的吗?
    • 上限为 9,999,999。看到这个答案:stackoverflow.com/a/2462211/106008
    • 是否有一个版本可以为“检查所有”和“取消检查所有”方案设置每个列表视图项的“检查”状态?
    【解决方案3】:
    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 等)上。

    【讨论】:

    【解决方案4】:

    如果用户先松开 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;
            }
        }
    }
    

    【讨论】:

    • 我无法对第一个答案发表评论,所以我发布了一个新答案(对此感到抱歉)
    • 这似乎与第一个答案没有什么不同(除了 if 语句中 chcks 的顺序)。我错过了什么吗?
    【解决方案5】:

    我无法对第一个问题发表评论,但是使用 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;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-06-01
      • 2019-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多