4

我正在使用 Compact Framework 开发一个智能设备项目。

我有一个ListView带有几个 checkableListViewItem的:属性CheckBoxes是真的。我一次只需要检查一个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:
        i.e. 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?

4

5 回答 5

12

好吧,我认为可能比使用 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];
}

我认为您会同意,重新分配 EventHandlers 比简单地检查存储对象的引用要差一些。

于 2012-12-13T12:07:29.003 回答
2

这是一种更简单的方法,可以重复用于多个列表。

private void listView_ItemCheck(object sender, ItemCheckEventArgs e)
        {
            var listView = sender as ListView;
            if (listView != null && e.NewValue == CheckState.Checked)
            {
                foreach (ListViewItem checkedItem in listView.CheckedItems)
                {
                    checkedItem.Checked = false;
                }
            }
        }

ItemCheck 事件在列表项状态更改之前触发,因此不需要额外的测试。

ItemCheck - 表示项目即将更改其检查状态。直到事件发生后,该值才会更新。

于 2016-07-08T02:20:43.183 回答
2

M Bak 您忘记在分配新值之前禁用项目检查事件。而且您的代码也将取消选中最后检查的值,因为您使用了已检查的事件。CheckedItems.Count 也将在 Checked 值更改后更改。固定解决方案是:

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;
        }
    } 
于 2017-07-18T09:24:46.003 回答
0

这么多代码和技巧...

listView.SelectionMode = System.Windows.Controls.SelectionMode.Single;
于 2013-08-14T12:35:46.543 回答
0
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;
    }
于 2014-11-03T21:23:44.627 回答