Trying to sort a ListView with unchecked items at the top and then by ID: the comparison program throws an odd exception

I am creating a desktop application for the desktop, and in my user interface I have a control ListViewthat lists all the elements in each list. Each element / row has a flag that updates the status of this element in the database when it is checked or unchecked. So far so good!

What I'm trying to do is sort the list each time I click on the checkbox, so that the list is always sorted using unchecked items at the top, and then by identifier (which is the value intstored in Tageach property ListViewItemwhen the list is loaded).

I wrote a custom comparison method IComparerand called Sort()in ListViewin the event handler ItemChecked:

/// <summary>
/// Complete or uncomplete a todo item when it 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();
}

Here is my comparator:

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 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 the item, the following exception occurs when trying to sort:

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

And in the debugger, if I check the property item1.Checkedin the comparison procedure, I see:

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

Another property is Checkeddisplayed in order. What am I doing wrong here?

+3
source share
2 answers

It looks like your IndexListViewItem is - -1( Checked uses Indexinternally). Usually in the case ListViewItemonly is added to ListViewItem.

, , . , Checked .

+3

0 -1, , , Compare(), .

-1

Source: https://habr.com/ru/post/1771276/


All Articles