C# 不允许ListView有零个选定项

C# 不允许ListView有零个选定项,c#,winforms,listview,C#,Winforms,Listview,我的项目是.NET/WinForms 我有一个列表视图,它总是充满了项目。我希望它总是有选择。但是,如果我单击列表视图项下面的空白区域,它将失去选择 列表有多个selection=true和hide selection=false。您需要处理ListView的SelectedIndexChanged事件,如果在该事件发生后没有选择项目,以编程方式重新选择最后一个已知选择。列表视图有一个SelectedIndexChanged事件。听一听,然后查询列表视图。SelectedItems.Count属

我的项目是.NET/WinForms

我有一个列表视图,它总是充满了项目。我希望它总是有选择。但是,如果我单击列表视图项下面的空白区域,它将失去选择


列表有多个selection=true和hide selection=false。

您需要处理ListView的
SelectedIndexChanged
事件,如果在该事件发生后没有选择项目,以编程方式重新选择最后一个已知选择。

列表视图有一个
SelectedIndexChanged
事件。听一听,然后查询
列表视图。SelectedItems.Count
属性-如果它为零,则选择第一个/最后一个选中的项目。

正如其他人所说,您应该查看
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;

}

您需要防止本机控件看到鼠标单击,以便它不会取消选择项目。向项目中添加一个新类并粘贴如下所示的代码。编译。将它从工具箱顶部放到表单上,替换现有的表单

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);
    }
}
使用系统;
使用系统图;
使用System.Windows.Forms;
类MyListView:ListView{
受保护的覆盖无效WndProc(参考消息m){
//吞下不在客户端区域的鼠标消息

如果(m.Msg>=0x201&&m.Msg如果您不需要multiselect,则以下操作有效。它的优点是不需要跟踪上次选择的项目

private void ListViewAny_SelectedIndexChanged(object sender, EventArgs e)
{
    if ((sender as ListView).FocusedItem != null)
    {
        (sender as ListView).FocusedItem.Selected = true;
    }
}

(无多选)

duplicate:duplicate subject only。该线程没有真正的答案。该线程的最高级答案是WPF,这是WinForms。有一种非常简单的方法……在listview属性中,将HideSelection设置为false,将FullRowSelect设置为true。@Alex感谢您的建议,但级别太低了一点。我想我会选择manual s根据下面的建议进行选择。奇数,我会考虑“手动设置选择返回”一个低级黑客。这是一个很好的解决方案,但我必须使它成为一个公共类,让它工作。
    private void LV_MouseUp(object sender, MouseEventArgs e)
    {
        if (LV.FocusedItem != null)
        {
            if (LV.SelectedItems.Count == 0)
                LV.FocusedItem.Selected = true;
        }
    }