Попытка сортировки ListView с непроверенными элементами вверху и затем по ID: процедура сравнения выдает странное исключение - PullRequest
3 голосов
/ 25 октября 2010

Я создаю настольное приложение со списком дел, и в моем пользовательском интерфейсе у меня есть элемент управления ListView, который перечисляет все элементы в каждом списке. Каждый элемент / строка имеет флажок, который обновляет статус этого элемента в базе данных, когда он отмечен или не отмечен. Пока все хорошо!

То, что я пытаюсь сделать, это пересортировать список при каждом нажатии флажка, чтобы список всегда сортировался с непроверенными элементами вверху, а затем по идентификатору (который является значением int, хранящимся в Tag свойство каждого ListViewItem при загрузке списка).

Я написал собственный компаратор, реализующий IComparer и вызывающий Sort() для ListView в обработчике ItemChecked:

/// <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;
    }
}

Однако, когда я проверяю элемент, при попытке сортировки выдается следующее исключение:

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 в процедуре сравнения, я вижу:

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

Свойство Checked другого элемента отображается нормально. Что я тут не так делаю?

Ответы [ 2 ]

3 голосов
/ 25 октября 2010

Похоже, что Индекс вашего ListViewItem равен -1 (свойство Проверено использует Index внутренне).Обычно это происходит только до того, как ListViewItem добавляется к ListView.

В вашем случае элемент мог быть временно удален из списка во время сортировки.Другими словами, доступ к свойству Checked из процедуры сортировки выглядит небезопасным.

0 голосов
/ 25 октября 2010

Вместо этого попробуйте вернуть 0, если -1, поскольку кажется, что значение, возвращаемое Compare(), становится индексом элемента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...