Подтвердить что ты не робот

Запретить ListView иметь нулевые выбранные элементы

Мой проект -.NET/WinForms.

У меня есть список, который всегда заполняется элементами. Я бы хотел, чтобы у него всегда был выбор. Однако, если я нажимаю на пустую область под элементами списка списка, она теряет выделение.

Список имеет множественный выбор = true и скрыть выбор = false.

4b9b3361

Ответ 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 - если он равен нулю, выберите первый/последний выбранный элемент.