试图在顶部未检查的项目一个ListView排序,然后按ID:比较常规抛出一个奇怪的异常抛出、然后按、常规、异常

2023-09-06 07:50:55 作者:别赖着曾经不放手

我建立一个桌面待办事项列表应用程序,并在我的UI我有一个的ListView 控制,列出了每个列表中的所有项目。每个项目/行都有一个复选框,其更新该项目的状态在数据库中被选中或取消选中时。到目前为止好!

I'm building a desktop to-do list app, and in my UI I have a ListView control which lists all the items in each list. Each item/row has a checkbox which updates the status of that item in the database when it is checked or unchecked. So far so good!

我所试图做的是重新排序列表每当复选框被点击,从而使列表始终排序在顶部的未检查的项目,然后通过ID(这是一个存储在标签INT 每个属性的ListViewItem 时,列表加载)。

What I am attempting to do is re-sort the list whenever a checkbox is clicked, so that the list is always sorted with the unchecked items at the top, and then by ID (which is an int value stored in the Tag property of each ListViewItem when the list is loaded).

我写了一个自定义比较实施的IComparer 并调用排序()的ListView ItemChecked 事件处理程序:

I've written a custom comparer implementing IComparer and call Sort() on the ListView in the ItemChecked event handler:

/// <summary>
/// Complete or uncomplete a todo item when it's checked/unchecked
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void _taskList_ItemChecked(object sender, ItemCheckedEventArgs e)
{
    var list = sender as ListView;
    var itemId = e.Item.Tag.ToString();

    if(e.Item.Tag != null)
    {
        if(e.Item.Checked)
            // Do some database stuff here to mark as complete
        else
            // Do some database stuff here to mark as not completed
    }

    // Resort the listview
    list.ListViewItemSorter = new TaskListComparer();
    list.Sort();
}

下面是我比较器:

public class TaskListComparer : IComparer
{
    public TaskListComparer()
    {
    }

    public int Compare(object a, object b)
    {
        // Convert the two passed values to ListViewItems
        var item1 = a as ListViewItem;
        var item2 = b as ListViewItem;

        // Get the unique ID's of the list items (stored in the Tag property)
        var item1Id = Convert.ToInt32(item1.Tag);
        var item2Id = Convert.ToInt32(item2.Tag);

        // First sort on the Checked property (unchecked items should be at the top)
        if (item1.Checked && !item2.Checked)
            return 1;
        else if (!item1.Checked && item2.Checked)
            return -1;

        // If both items were checked or both items were unchecked, 
        // sort by the ID (in descending order)
        if (item1Id > item2Id)
            return 1;
        else if (item1Id < item2Id)
            return -1;
        else
            return 0;
    }
}

然而,当我检查的项目,以下异常被抛出时的那种尝试:

However, when I check an item, the following exception is thrown when the sort is attempted:

System.ArgumentOutOfRangeException was unhandled
    Message="InvalidArgument=Value of '-1' is not valid for 'index'.\r\nParameter name: index"
    Source="System.Windows.Forms"
    ParamName="index"

并在调试,如果我检查 item1.Checked 属性比较常规我看到:

And in the debugger, if I inspect the item1.Checked property in the compare routine I see:

'item1.Checked' threw an exception of type 'System.ArgumentOutOfRangeException'

在其他项目的检查属性显示的罚款。我在做什么错在这里?

The other item's Checked property shows up fine. What am I doing wrong here?

推荐答案

它看起来像的指数你的的ListViewItem 1 (即< A HREF =htt​​p://msdn.microsoft.com/en-us/library/system.windows.forms.listviewitem.checked.aspx相对=nofollow>经过属性使用首页内部)。这是正常的情况下,只有在的ListViewItem 添加到的ListView

It looks like the Index of your ListViewItem is -1 (the Checked property uses Index internally). That's normally the case only before the ListViewItem is added to the ListView.

在你的情况下,该项目可能已被暂时从名单中排序中删除。换句话说,它看起来并不安全地从一种例行访问检查属性。

In your case, the item might have been temporarily removed from the list during sorting. In other words, it does not look safe to access the Checked property from a sort routine.