一次只检查一个ListViewItem
我正在使用Compact Framework开发智能设备项目。
我有一个带有几个可检查ListViewItem
:属性CheckBoxes
为true。 我需要在时间只检查一个ListViewItem
,所以我订阅了ItemCheck
事件:
// I need to know the last item checked private ListViewItem lastItemChecked; private void listView_ItemCheck(object sender, ItemCheckEventArgs e) { if (lastItemChecked != null && lastItemChecked.Checked) { /* I need to do the following to prevent infinite recursion: ie subscribe and then unsubscribe the ItemCheck event. */ listView.ItemCheck -= listView_ItemCheck; lastItemChecked.Checked = false; listView.ItemCheck += listView_ItemCheck; } lastItemChecked = listView.Items[e.Index]; }
有没有更好的方法来防止无限递归,从而防止Stack Overflow
?
好吧,我认为比使用EventHandlers更好的方法是检查lastItemCheck是否是EventArgs中的当前项。 像这样:
// I need to know the last item checked private ListViewItem lastItemChecked; private void listView_ItemCheck(object sender, ItemCheckEventArgs e) { // if we have the lastItem set as checked, and it is different // item than the one that fired the event, uncheck it if (lastItemChecked != null && lastItemChecked.Checked && lastItemChecked != listView.Items[e.Index] ) { // uncheck the last item and store the new one lastItemChecked.Checked = false; } // store current item lastItemChecked = listView.Items[e.Index]; }
我认为您同意,重新分配EventHandler比仅仅检查存储对象的引用要差一些。
这是一种更简单的方法,可以重复用于多个列表。
private void listView_ItemCheck(object sender, ItemCheckEventArgs e) { var listView = sender as ListView; if (listView != null) { for (var i = 0; i < listView.CheckedItems.Count; i++) { listView.CheckedItems[i].Checked = false; } } }
ItemCheck事件在列表项状态更改之前触发,因此不需要其他测试。
ItemCheck - 表示项目的检查状态将更改。 事件发生后才会更新该值。
另一个回答检查当前项目是否与当前项目不匹配没有任何用处,因为在此事件完成后进行选择,因此如果将其设置为false则无关紧要。
lastItemChecked != listView.Items[e.Index]
M Bak您忘记在分配新值之前禁用项目检查事件。 并且您的代码也将取消选中上次检查的值,因为您使用了checked事件。 Checked值更改后,CheckedItems.Count也会更改。 固定解决方案是:
private void LstFirstPageBanner_ItemCheck(object sender, ItemCheckEventArgs e) { var listView = sender as ListView; if (listView != null) { var checkedCount = listView.CheckedItems.Count; listView.ItemCheck -= LstFirstPageBanner_ItemCheck; for (var i = 0; i < checkedCount; i++) { listView.CheckedItems[i].Checked = false; } listView.ItemCheck += LstFirstPageBanner_ItemCheck; } }
这么多代码和技巧……
listView.SelectionMode = System.Windows.Controls.SelectionMode.Single;
private void listView1_ItemChecked(object sender, ItemCheckedEventArgs e) { listView1.ItemChecked -= listView1_ItemChecked; foreach (var item in listView1.CheckedItems) { if (e.Item != item) { ((ListViewItem)item).Checked = false; } } listView1.ItemChecked += listView1_ItemChecked; }