I have a Silverlight project where the main objects are just a bunch of nodes that are joined to each other. A parent node can have many children.
I want to be able to bind the nodes to an itemscontrol or similar and so was wondering how to best structure the parent child relationship.
Is it OK to create a flat top level list of all nodes (List allNodes) and add each node to that, binding the list to the itemscontrol, then on top of that add each node to it's parent's 'childnodes' list to establish the structure - or am I doing some kind of ugly doubling up?
Just hoping there is some kind of best practice or pattern I can latch on to
Thanks
You should use the treeview found in the official silverlight toolkit. Here is an online demo.
Related
I have a TreeView which data source is generated in runtime through code to which I don't have access. Its hierarchical data, nodes of tree with 2, 3 or 4 depth levels. I have to make the same structured tree with RadioButtons corresponding to every object in first tree. Is there a way to iterate through every element of TreeView or another method to do my task?
In WPF, we use DataTemplates, or in your case HierarchicalDataTemplates to define how our data should be presented. You already have the data in the first TreeView and that should be accessible from its ItemsSource or Items properties. Therefore, all you need to do is to define another HierarchicalDataTemplate to display the same data object the way that you want it. There is no need to manually iterate through all of the nodes from the original TreeView.
Is there any way to create infinite children nodes in TreeView using DataTemplate?
I read lots of tutorials, but all of them show only manually populated TreeView. I need to populate my TreeView from database.
Try using HierarchicalDataTemplate; To populate data from DB you will have to first fetch the data, create proper DataModel objects and then use them to populate the TreeView. I would also suggest you to use MVVM for this, MVVM makes it very easy to work with TreeView.
Have a look at following great article from Josh Smith explaining both these (and much more)-
Simplifying the WPF TreeView by Using the ViewModel Pattern
I want to create an expandable empty treenode in C#, i.e. a treenode which is empty and has the [+] sign beside it. The reason is because initially it is empty, but once a node is clicked, I want to populate it with many child nodes.
The only problem I am facing is that empty treenodes aren't expandable, so I don't know what to do. Is there a way to solve this problem, or are there any workarounds?
You have to redraw the tree itself, or create an empty node and simply remove it when the parent node is expanded.
Personally, I'd go for option b). I've done this before, a while ago and thanks to the events raised by the TreeView it pretty easy to accomplish.
You can give the empty node a value like 'Loading...' so it gives some feedback to the user as well. :)
Add a dummy child node, and remove it when you expand.
Have a look at Josh Smiths excellent tutorial on treeviews. It allows lazy loading of child tree nodes by having a dummy node that is removed upon expansion.
My data comes from a database. I have an item data table with some basic properties.
Item
{
ID,
Name,
Description,
...
}
Then I have a many to many relationship table with:
Parent
{
ParentID,
ChildID
}
I'm iterating through each item and displaying its children; and its children's children, etc. I assume this would best be accomplished with nested repeaters, but I could be wrong.
How do I get multiple heirarchical levels using asp:repeaters? I've only ever used one nested repeater, I have no idea how to do 3+.
Personally I probably do this by creating a custom control with an Item property and some sort of either Parents or Children property. The control would display details on Item, and then use a repeater to show each element in Parents / Children, where for each item the repeater recursively uses the same control to render the item.
I would do what #Kragen said. But if you really think that creating two components is too much you should use one repeater and two foreach loops in on data bound.
Using two repeaters one inside of another is overcomplicated not to mention 3 repeaters :).
A Parent-Child relationship, which is many-to-many? This doesn't make sense, at least calling them a parent and a child doesn't make sense. If it is really many-to-many, it's a network, if a child only has ONE parent, then it is a hierarchy.
With the former, I'm not sure visualizing them in that way is any good. How do you visualize a child with more than one parent?
With the latter, why not use a TreeView with a custom item template? It handles all the hierarchy stuff automatically. The problem with repeaters is that if you are not doing them dynamically (creating them in code), then the level of nesting is fixed and you cannot go as much as you want. Doing them dynamically would work, but would bring overhead.
I'm not very sure what exactly you are trying to accomplish. Maybe providing some more details about the end-result you need to see would be helpful.
Background
I have a TreeView that follows the MVVM design pattern and supports multiple selection by recording TreeViewItem selections in a List. As it stands there are several types of TreeViewItems available for the user to select.
They are:
Two Root nodes of type WorldFolder and MyDataFodler which can contain child Folder types
Child Folder nodes of types LocationFolder, PersonFolder, CollectionFolder
Child Item nodes of type LocationItem, PersonItem
CollectionFolder can contain child nodes of Folder types
In all this works very well with very little code and supports collections of Locations and People and furthermore Collections within Collections.
Problem / Question
My top level view-model keeps track of the selection state of TreeViewItems and the current selection may be a combination of Item, Folder or even Root type nodes. Depending on the user's selection I want to create a dynamic ContextMenu. So far this works! When I select several LocationItem and/or PersonItem type nodes my view-model generates a custom ContextMenu. The problem is the complexity! My view-model is quickly turning into dozens of if/else if/else statements to capture all the possible permutations!
For example:
if (_selectedItems.All(item => item is PersonItem)) // Only people selected
{
// Create ContextMenu based on only PersonItems
}
else if( _selectedItems.All(item => item is LocationItem)) // Only Locations
{
// Create ContextMenu based only on LocationItems
}
...
Is there a better way to handle all the possible permutations of user choices and generate my ContextMenus more efficiently?
* Sorry about the code formatting, it's been giving me grief all week *
I can't remember where I read this wise saying:
The best way to work with a TreeView is not not to work with the TreeView
What does this mean? Move the functionality into the tree nodes and keep the tree view as thumb as possible. Unfortunately, by default the tree node does not many events, though, it's easy to redirect the tree view events to the nodes.
Once done, you can override the ContextMenuStrip property in your nodes. The first selected node creates the list of ToolStripItems it wants to handle and asks the tree view which are allowed (e.g. with a FilterMenuItems(desiredItems) method). The tree view asks all selected nodes which of the nodes they would be able to handle. The result is your context menu.
This should work with almost any count of different nodes and keeps the tree (nodes) easy to maintain.
Edit: Dang! Missed the WPF tag, so I cannot asses the available events, since I did not yet work with WPF