Hoping someone can comment on a more effective way to do this: I have a generic list of work items that represents a user's to-do list. Currently, this is sorted and displayed in an Obout Treeview by due date only and works fine.
Now we're looking to update this by allowing users to sort their to-do list by applying a primary and secondary "filter" (i.e., by due date and then by received date or similar) to that treeview, such that the treeview displays the primary sort as the parent and the secondary sort as children. The actual items would be displayed as grandchildren, like so:
Due Date
- Received Date
-- Work Item
-- Work Item
- Received Date
-- Work Item
Due Date
... etc
Obout Treeview has some crucial restrictions, as far as I can tell:
- Parent nodes must be created before their children
- Nodes cannot be deleted once created
- There is no method to see if other nodes (parent, sibling, child) exist, so you can't programmatically tell if a node would be a duplicate on the server side.
I'm modifying some old code, so be gentle with my example. I had to take out a lot to clarify what it's doing.
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);
}
}
}
How can I more effectively create the root-first hierarchy for the Obout tree from the generic list, with minimal traversing over the dataset again and again for unique values?
Creating the structure with hard-coded sorts is messy enough, but attempting to code this in a way that cleanly allows for user-defined sorts (without an explosion of subclasses or methods) has really got me stumped. I would love to hear any suggestions at all!
Thank you.
You're not sorting the data by those dates, you're grouping the data by those data (and then sorting those groups).
To group items based on a field, simply use
GroupBy.You just need to group your items by the first field, the group each of those groups on the second field, and add in the ordering clauses as appropriate to order the groups themselves.
Or, if you prefer to use method syntax:
Once you've transformed the data into the appropriate model, translating that model into a TreeView should be straightforward, you simply need to iterate each group and create an item for that group, then iterate the items in that group adding child nodes for each item, and do the same for those children (which are themselves groups) to add the grandchildren.