2009-06-19 1 views
18

Как и у субъекта, у меня есть список, и я хотел добавить Ctrl + A выделить все ярлыки на него. Моя первая проблема заключается в том, что я не могу понять, как программно выбирать все элементы в списке. Похоже, что это должно быть относительно легко, например ListView.SelectAll() или ListView.Items.SelectAll(), но это, похоже, не так. Моя следующая проблема заключается в том, как определить комбинацию клавиш для ListView. Я делаю это в событии KeyUp, но как бы вы проверили сразу два нажатия? Или это свойство, которое вы установили?Добавление выделенного ярлыка (Ctrl + A) в список .net listview?

Любая помощь здесь будет замечательной.

ответ

30

Вы могли бы достичь и с чем-то вроде этого:

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

У вас есть или в заявлении, если - должно быть AND. –

+0

Исправлено - я просто видел это. :) –

+0

Ха, я знал, что это будет что-то смехотворно легкое. Благодарю. – ryanulit

21

Эти работы для небольших списков, но если есть 100000 элементов в виртуальном списке, это может занять много времени. Это, вероятно, избыточна для ваших целей, но только в том случае ::

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); 
+0

Есть ли какие-либо предпосылки для запуска этого кода? Я пытаюсь использовать обычный .NET ListView с CheckBoxes = true. И это ничего не делает. –

+0

Можете ли вы предоставить версию vb.net – Smith

+0

Спасибо большое, это отлично работает! Я использую listview в виртуальном режиме. Но почему-то количество предметов кажется ограниченным. Вы уверены, что возможно 100 000 строк? – brighty

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

Я не смог опубликовать комментарий к первому ответу, поэтому я опубликовал новый ответ (извините за это) – olorin

+0

Это, похоже, не отличается от первого ответа (кроме порядка chcks в инструкции if). Я что-то упускаю? –

+0

Другой ответ изначально использовался 'KeyUp' и был отредактирован. – JYelton

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; 
     } 
    } 
} 
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 и т.д.

+1

+1 для точки «Чтобы сделать это только на Ctrl + A», решение Grammarian лучше для производительности, хотя – yclkvnc