代码之家  ›  专栏  ›  技术社区  ›  Mark Bell

尝试用顶部未选中的项对ListView排序,然后按ID:Compare例程引发异常

  •  3
  • Mark Bell  · 技术社区  · 14 年前

    我正在构建一个桌面待办事项列表应用程序,在我的用户界面中我有一个 ListView 控件,该控件列出每个列表中的所有项。每个项目/行都有一个复选框,当选中或未选中时,该复选框将更新数据库中该项目的状态。到现在为止,一直都还不错!

    我要做的是每当单击复选框时重新排序列表,这样列表总是按照顶部未选中的项目排序,然后按ID(这是一个 int 值存储在 Tag 每个的属性 ListViewItem 当加载列表时)。

    我编写了一个自定义比较器实现 IComparer 然后打电话 Sort() 列表视图 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 回复  |  直到 14 年前
        1
  •  3
  •   Frédéric Hamidi    14 年前

    看起来像 Index 您的 ListViewItem -1 (the Checked 属性用途 Index 内部)。通常情况下只有在 列表视图项 添加到 ListView

    在您的情况下,该项目可能在排序过程中被临时从列表中删除。换句话说,访问 Checked 属性。

        2
  •  -1
  •   abatishchev Karl Johan    14 年前

    试着回来 0 相反,如果 -1 因为似乎返回的值 Compare() 成为项目的索引。