一次只检查一个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; }