从平面LINQ结果创建分层列表

时间:2016-05-05 00:04:30

标签: c# linq treeview obout

希望有人可以评论更有效的方法:我有一个代表用户待办事项列表的通用工作项列表。目前,它仅按截止日期在Obout Treeview中排序和显示,并且工作正常。

现在,我们正在寻求更新此功能,允许用户通过应用主要和辅助"过滤器"来对用户的待办事项列表进行排序。 (即,按截止日期,然后按接收日期或类似日期)到树视图,以便树视图显示主要排序作为父级,次要排序显示为子级。实际项目将显示为孙子,如下所示:

Due Date
- Received Date
-- Work Item
-- Work Item
- Received Date
-- Work Item 
Due Date

...等

据我所知,Obout Treeview有一些至关重要的限制:

  1. 必须在子节点之前创建父节点
  2. 创建后无法删除节点
  3. 没有方法可以查看是否存在其他节点(父节点,兄弟节点,子节点),因此您无法以编程方式判断节点是否在服务器端重复。
  4. 我修改了一些旧代码,所以要对我的例子保持温和。我不得不花很多时间来澄清它在做什么。

    public void generateOboutTreeContent()
    {
        // Add unique root nodes.
        switch (primarySort)
        {
            [...]
            case SortOption.ByDueDate:
                addNodesForDueDates(true);
                break;
            [...]
        }
    
        // Then add child nodes for each root node.
        switch (secondarySort)
        {
            [...]
            case SortOption.ByReceivedDate:
                addNodesForReceivedDates();
                break;
            [...]
        }
    
        // Finally, add all the actual items as grandchildren.
        foreach (WorkItem item in WorkQueue)
        {
            tree.Add(parentID, item.ID, item.url, false);
        }
    }
    
    private void addNodesForDueDates(bool isRootNode = false)
    {
        var uniqueNodes = workQueue.GroupBy(i => i.DueDate).Select(group => group.First()).ToList();
        foreach (classWorkItem node in uniqueNodes)
        {
            var dueDate = node.DueDate;
            if (isRootNode)
            {
                tree.Add("root", dueDate, dueDate , false);
            }
            else
            {
                tree.Add(parentID, dueDate, dueDate, false);
            }
        }
    }
    

    如何从通用列表中更有效地为Obout树创建根优先层次结构,对数据集一次又一次地遍历唯一值?

    使用硬编码排序创建结构非常混乱,但尝试以干净地允许用户定义的排序(没有子类或方法的爆炸)的方式对此进行编码确实让我感到难过。我很乐意听到任何建议!

    谢谢。

1 个答案:

答案 0 :(得分:2)

您不按这些日期排序数据,您按照这些数据对数据进行分组(然后对这些组进行排序)。< / p>

要根据字段对项目进行分组,只需使用GroupBy

您只需要按第一个字段对项目进行分组,将第二个字段中的每个组分组,然后根据需要添加排序子句,以便自己对组进行排序。

var query = from item in data
            group item by item.DueDate into dueDateGroup
            orderby dueDateGroup.Key
            select from item in dueDateGroup
                    group item by item.RecievedDate into recievedDateGroup
                    orderby recievedDateGroup.Key
                    select recievedDateGroup;

或者,如果您更喜欢使用方法语法:

var query2 = data.GroupBy(item => item.DueDate)
    .OrderBy(group => group.Key)
    .Select(dueDateGroup =>
        dueDateGroup.GroupBy(item => item.RecievedDate)
            .OrderBy(group => group.Key));

一旦您将数据转换为适当的模型,将该模型转换为TreeView应该很简单,您只需要迭代每个组并为该组创建项目,然后迭代该组中的项目添加每个项目的子节点,并为那些孩子(它们自己是组)做同样的事情来添加孙子。