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