C# 将全选快捷方式 (Ctrl + A) 添加到 .net 列表视图?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1019388/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 05:40:28  来源:igfitidea点击:

Adding a select all shortcut (Ctrl + A) to a .net listview?

c#.netlistviewkeyboard-shortcuts

提问by ryanulit

Like the subject says I have a listview, and I wanted to add the Ctrl+ Aselect all shortcut to it. My first problem is that I can't figure out how to programmatically select all items in a listview. It seems like it should be relatively easy, like ListView.SelectAll()or ListView.Items.SelectAll(), but that doesn't appear to be the case. My next problem is how to define the keyboard shortcut for the ListView. Do I do it in a KeyUpevent, but then how would you check two presses at once? Or is it a property that you set?

就像主题说我有一个列表视图,我想向它添加Ctrl+ 全A选快捷方式。我的第一个问题是我不知道如何以编程方式选择列表视图中的所有项目。看起来它应该相对容易,比如ListView.SelectAll()ListView.Items.SelectAll(),但事实并非如此。我的下一个问题是如何定义ListView. 我会在一个KeyUp事件中这样做,但是你如何一次检查两次印刷机?或者它是您设置的属性?

Any help here would be great.

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

采纳答案by Shane Fulmer

You could accomplish both with something like this:

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

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

回答by Grammarian

These works for small lists, but if there are 100,000 items in a virtual list, this could take a long time. This is probably overkill for your purposes, but just in case::

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

and you use it like this::

你像这样使用它::

NativeMethods.SelectAllItems(this.myListView);

回答by olorin

The first solution won't work if user releases the Ctrlkey first.

如果用户先释放Ctrl密钥,第一个解决方案将不起作用。

You should use the KeyDownevent instead:

您应该改用该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;
        }
    }
}

回答by Vitaliy.Vol

I could not comment on the first question, however solution with KeyDown does not work for me, because system immediately reacts on LeftCtrl pressed and so skips CTRL+A. From other side KeyUp works correctly.

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

回答by nyrocron

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

To onlydo it on Ctrl+A, not on other combinations like Ctrl+Shift+A etc.

去做就按Ctrl + A,不是像按Ctrl + Shift + A等其他组合