关于c#:如何同步ListView中的选定项目和选中的项目?

How to sync selected items and checked items in a ListView?

我有一个ListView,其属性CheckBoxes设置为true,并且具有以下事件处理程序:

1
2
3
4
private void listView1_ItemCheck(object sender, ItemCheckEventArgs e)
{
    listView1.Items[e.Index].Selected = e.NewValue == CheckState.Checked ? true : false;
}

使用键盘:

我可以使用箭头键向左或向右移动选择,并使用空格键(取消)检查项目。我可以使用Shift键选择多个项目。

问题:当按下Space键取消选中其中一项时,所选内容将自动设置为单个项目,即当前关注的项目。

使用鼠标:

选择和选中的元素似乎是同步的,直到我选中两个项目,然后在其两个复选框之一被单击时单击鼠标左键,此时选中被清除并且选中的项目全部变为未选中状态。

截图示例:

初始状态:

Initial

预期的行为:应保持选中并选中两个复选框之一(在上一步中未单击的复选框)。

注意:我希望也可以使用ListView的其他视图,LabelEdit属性,拖动


由于此问题在注释中有所改进,因此我决定删除所有内容并发布完成的代码。

  • 创建空表格
  • 向其添加名称为listView1的ListView组件
  • 将此代码粘贴到您的.cs文件中

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace Magacin
{
    public partial class TestForm : Form
    {
        bool HandleSelectionChange = true;
        bool HandleCheckChange = true;
        bool TempStopDeslect = false;

        bool dragging = false;
        bool multiJob = false;


        public TestForm()
        {
            InitializeComponent();


            listView1.CheckBoxes = true;
            this.listView1.ItemCheck += OnCheck;
            this.listView1.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.listView1_ItemSelectionChanged);
            this.listView1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.listView1_KeyDown);
            this.listView1.KeyUp += new System.Windows.Forms.KeyEventHandler(this.listView1_KeyUp);
            this.listView1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.listView1_MouseDown);
            this.listView1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.listView1_MouseUp);


            listView1.Items.Add("Item1");
            listView1.Items.Add("Item2");
            listView1.Items.Add("Item3");
        }

        private ListViewItem GetItemFromPoint(ListView listView, Point mousePosition)
        {
            Point localPoint = listView.PointToClient(mousePosition);
            return listView.GetItemAt(localPoint.X, localPoint.Y);
        }

        private void OnCheck(object sender, ItemCheckEventArgs e)
        {
            if (!HandleCheckChange)
                return;

            ListViewItem item = GetItemFromPoint(listView1, Cursor.Position);

            if (item == null)
                return;

            if (e.Index != item.Index)
            {
                TempStopDeslect = true;
                e.NewValue = e.CurrentValue;
                return;
            }

            HandleSelectionChange = (multiJob) ? false : true;
            if (e.NewValue == CheckState.Checked)
            {
                listView1.Items[e.Index].Selected = true;
            }
            else
            {
                listView1.Items[e.Index].Selected = false;
            }
            HandleSelectionChange = true;
        }
        private void listView1_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            if (!HandleSelectionChange)
                return;

            bool temp = e.IsSelected;

            if (!TempStopDeslect)
            {
                if (!multiJob && !dragging)
                {
                    foreach (ListViewItem i in listView1.Items)
                    {
                        i.Checked = false;
                        i.Selected = false;
                    }
                }
            }
            else
                TempStopDeslect = false;

            HandleCheckChange = false;
            e.Item.Selected = temp;
            e.Item.Checked = e.IsSelected;
            HandleCheckChange = true;
        }

        private void listView1_MouseDown(object sender, MouseEventArgs e)
        {
            ListViewItem item = GetItemFromPoint(listView1, Cursor.Position);
            if (item == null)
                dragging = true;
        }
        private void listView1_MouseUp(object sender, MouseEventArgs e)
        {
            dragging = false;
        }

        private void listView1_KeyDown(object sender, KeyEventArgs e)
        {
            if(e.KeyCode == Keys.Control) // Change this to whatever you want
                multiJob = true;
        }
        private void listView1_KeyUp(object sender, KeyEventArgs e)
        {
            multiJob = false;
        }
    }
}

我想我有想要的行为。如果不问我在那边,我会编辑。在大多数情况下,它正在移动/更改布尔值,但是如果您不习惯它也可以。