views:

938

answers:

3

I have a Silverlight TreeView control that I'm dynamically populating when a specific node is clicked. For example, I load the first generation (level) of nodes, then when the user clicks on one of the nodes, I use the Selected event to populate that node's children, etc, etc. I'm sending back from my database a bool value with each node value that indicates whether or not the new nodes have children nodes.

I am wanting to set the expand arrow to show in front of new nodes that have a child, but the catch is that its children will not be populated yet. I thought maybe setting the HasChild to my bool value, but HasChild is read-only. Any suggestions would be very much appreciated.

A: 

If you're familiar with dependency properties, you could create a dependency property that would be settable by you in code and gettable in the xaml so it could be bound to.

This would allow you to use a ValueConverter to render the visibility of the arrow.

TreeUK
I tried to use your suggested method, but I get the following error:<br><br>Unhandled Error in Silverlight Application Cannot set read-only property HasItems. at System.Windows.Controls.TreeViewItem.OnHasItemsPropertyChanged(etc, blah, blah..)<br><br>Here is the code that I used to try to update the Dependency Property of my TreeViewItem:<br><br>TreeViewItem tvi = new TreeViewItem() { Header = x.UserName, Name = x.UserName };tvi.SetValue(TreeViewItem.HasItemsProperty, true);<br><br>I'm probably missing something. Thank you!
Jeremy Sullivan
I think HasItems is just a reflection of whether the count of items is more than 0. So you wouldn't set it directly, rather, ensure it has items :)
TreeUK
I need to fake it out so that it thinks it has items without actually having the items populated at that time.
Jeremy Sullivan
+1  A: 

Just a add blank treeviewitem when it's collapsed just to show the arrow.

But when expanded by the user, clear that blank child, and do an async call to get the real children.

Set the UserState to the parent treeviewitem or id when doing the GetChildrenAsync call.

When they arrive, the UserState should be that parent treeviewitem or id, when you find that parent which you just set it's itemsource to the e.Result.

Paully
I thought of the blank child and tried that before. It works great for most, but then I get this weird error with some data that say that a certain node with a specific name (ie 4555667) already exists. I run through my debugger and triple check my data but I can't see where it would ever be duplicated.
Jeremy Sullivan
That's too bad, mine works out real well. Are you sure you are clearing existing children before adding again? Can you tell what method or component is the source of the error?
Paully
I have two functions for filling nodes: one that does the initial fill and one that does all the subsequence children. My first function will populate perfectly. In one example, I have 10 records with 4 of them have children (the blank children). When I run my fill children function, if a node contains more than one child node that has child nodes, it gives me an unhandled error saying that a node already exists with that name (I name all nodes with the ID of the node and I've verified that there are no data redundancies.) Would you like to see my code?
Jeremy Sullivan
Sure, post it and I will check out the code. I'm using just 1 generic function to do root and children. The Parent property of the root is always null. I don't populate the NAME property, just the DataContext properties of my TreeViewItems. Please show some code, thanks.
Paully
A: 

another idea to do it in Xaml http://bea.stollnitz.com/blog/?p=54

Mev