Hi all,
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!
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).
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();
}
Here is my comparer:
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"
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?