How to sync selected items and checked items in a ListView?
我有一个ListView,其属性
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键取消选中其中一项时,所选内容将自动设置为单个项目,即当前关注的项目。
使用鼠标:
选择和选中的元素似乎是同步的,直到我选中两个项目,然后在其两个复选框之一被单击时单击鼠标左键,此时选中被清除并且选中的项目全部变为未选中状态。
截图示例:
初始状态:
然后在第一个复选框上单击鼠标左键,然后在第二个复选框上单击鼠标左键后:
然后在两个复选框中的任何一个上单击鼠标左键后,再次恢复初始状态:
预期的行为:应保持选中并选中两个复选框之一(在上一步中未单击的复选框)。
注意:我希望也可以使用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; } } } |
我想我有想要的行为。如果不问我在那边,我会编辑。在大多数情况下,它正在移动/更改布尔值,但是如果您不习惯它也可以。