Запретить ListView иметь нулевые выбранные элементы
Мой проект -.NET/WinForms.
У меня есть список, который всегда заполняется элементами. Я бы хотел, чтобы у него всегда был выбор. Однако, если я нажимаю на пустую область под элементами списка списка, она теряет выделение.
Список имеет множественный выбор = true и скрыть выбор = false.
Ответы
Ответ 1
Вам нужно, чтобы нативный элемент управления не видел щелчок мыши, чтобы он не отменил выбор элемента. Добавьте новый класс в свой проект и вставьте код, показанный ниже. Компиляция. Снимите его с верхней части панели инструментов на свою форму, заменив существующий.
using System;
using System.Drawing;
using System.Windows.Forms;
class MyListView : ListView {
protected override void WndProc(ref Message m) {
// Swallow mouse messages that are not in the client area
if (m.Msg >= 0x201 && m.Msg <= 0x209) {
Point pos = new Point(m.LParam.ToInt32());
var hit = this.HitTest(pos);
switch (hit.Location) {
case ListViewHitTestLocations.AboveClientArea :
case ListViewHitTestLocations.BelowClientArea :
case ListViewHitTestLocations.LeftOfClientArea :
case ListViewHitTestLocations.RightOfClientArea :
case ListViewHitTestLocations.None :
return;
}
}
base.WndProc(ref m);
}
}
Ответ 2
Как и все остальные, событие SelectedIndexChanged
- это то, на что вы должны обратить внимание, однако вы должны использовать его в сотрудничестве с событием ItemSelectionChanged
. Вот код, который я только что приготовил:
// Holds the last selected index
private int _previousIndex = -1;
// Restores the previous selection if there are no selections
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
if (listView1.SelectedIndices.Count == 0)
{
if (_previousIndex >= 0)
{
listView1.SelectedIndices.Add(_previousIndex);
}
}
}
// Records the last selected index
private void listView1_ItemSelectionChanged(object sender,
ListViewItemSelectionChangedEventArgs e)
{
if (e.IsSelected)
{
_previousIndex = e.ItemIndex;
}
}
Для целей чистого повторного использования кода, вероятно, стоит поставить этот код в новый UserControl и иметь свойство, которое определяет, следует ли потерять последний выбор:
public class CustomListView : ListView
{
protected CustomListView()
{
this.SelectedIndexChanged += new EventHandler(CustomListView_SelectedIndexChanged);
this.ItemSelectionChanged += new ListViewItemSelectionChangedEventHandler(CustomListView_ItemSelectionChanged);
}
void CustomListView_SelectedIndexChanged(object sender, EventArgs e)
{
if (this.MaintainLastSelection && this.SelectedIndices.Count == 0)
{
if (_previousIndex >= 0)
{
this.SelectedIndices.Add(_previousIndex);
}
}
}
void CustomListView_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{
if (e.IsSelected)
{
_previousIndex = e.ItemIndex;
}
}
private int _previousIndex = -1;
public bool MaintainLastSelection
{
get { return _maintainLastSelection; }
set { _maintainLastSelection = value; }
}
private bool _maintainLastSelection;
}
Ответ 3
Это работает, если вам не нужен мультиселектор. Преимущество состоит в том, что не нужно отслеживать, какой элемент был выбран последним.
private void ListViewAny_SelectedIndexChanged(object sender, EventArgs e)
{
if ((sender as ListView).FocusedItem != null)
{
(sender as ListView).FocusedItem.Selected = true;
}
}
Ответ 4
private void LV_MouseUp(object sender, MouseEventArgs e)
{
if (LV.FocusedItem != null)
{
if (LV.SelectedItems.Count == 0)
LV.FocusedItem.Selected = true;
}
}
(без мультиселекса)
Ответ 5
Вам нужно обработать событие SelectedIndexChanged
в ListView и в случае, если элемент не выбран после этого события, программно переустановите последний известный выбор.
Ответ 6
ListView
имеет событие SelectedIndexChanged
. Прослушайте это, а затем запросите свойство listView.SelectedItems.Count
- если он равен нулю, выберите первый/последний выбранный элемент.