I have a WPF TreeView that is bound to a collection of custom objects - each of which has an IsExpanded property to expand the container TreeViewItem. I want to be able to programmatically access each TreeViewItem's control contents without expanding the parent TreeViewItem in the visual tree. However, when I attempt to access said items without expanding their parent it seems as if they have not been added to the visual tree yet. Does anyone know a work around for this?
Related
I found this tutorial Using a Grid as the Panel for an ItemsControl but I couldn't get it to work.
I get this exception:
'Cannot explicitly modify Children collection of Panel used as ItemsPanel for ItemsControl. ItemsControl generates child elements for Panel.'
caused by grid.Children.Add(child) in this loop
foreach (FrameworkElement child in phantom.Children.ToList())
{
phantom.Children.Remove(child);
grid.Children.Add(child);
// ensure the child maintains its original datacontext
child.DataContext = phantom.DataContext;
}
Is there any work around possible by inheriting from ItemsPanel?
Shoehorning Grid into an ItemsControl is not a good idea.
You loose the function of an ItemsControl. Peter Duniho mentioned in the comments that an ItemContainer is where you see attached properties. For my application I needed to use the Selector functionality. If I used a Grid I would have had to implement this myself but I saved myself a lot of trouble just using an Listbox.
If you where wanting to use a Grid I suggest you look into the ListView as well as GridView. And if this isn't flexible enough you can always write your own ViewBase.
I am new to these stuffs. Hence I request for your help.I want to delete and add a node to a treeview in WPF MVVM. I have managed to create the treeview using :
http://www.codeproject.com/Articles/354853/WPF-Organization-Chart-Hierarchy-MVVM-Application
but now I am not able to figure out how can I add/delete a node and then refresh the treeview.
Help is appreciated.
That is the problem with copying other people's code and not bothering to find out how it works. In WPF, we manage data elements, not UI elements, so to add another item into any UI container control, we simply add a data item into whichever data collection that is data bound to the ItemsSource property of the container control. In your linked article, you can see the following:
Tree View
The DataContext of the TreeView is the OrgTreeViewModel. We set the TreeView's ItemsSource to the Root property of the OrgTreeViewModel, which is the top-most node in the hierarchy.
It therefore seems as though you have a collection property named Root in your OrgTreeViewModel view model class. So, all you need to do to add a new item into your TreeView is to add a new data object into your Root collection. If that tutorial is any good, then the UI will automatically update, showing the new item.
In my scenario, I'd like to be able to have a user double-click on an TreeViewItem to 'edit it'. In which case I would like to have that item expand in place (sliding the TreeViewItems below it down, so layout transform?), and show and edit form in place of the selected item. So, my question is, can I accomplish this by switching out the ItemTemplate for the double-clicked item? If so, I'm not sure how to approach this.
I have double-click attached event working on TreeViewItems and I have access to the TreeViewItem in my callback, I would optimally switch out the item's ItemTemplate at that point. My TreeView is built using a HierarchicalDataTemplate in a static resource for ItemTemplate and ViewModels to back the data.
Any guidance on this approach or any other suggestions to accomplish this scenario are appreciated!
You can change dynamically ItemTemplate for the clicked TreeViewItem.
Do it calling DependencyObject.SetCurrentValue()
And do not forget to restore the original local value which you should save before changes. Use ReadLocalValue() for this.
You need to define conditions when to restore original template (probably when selection changes.
You can also try to accomplish the task in a more MVVM way.
Just add an attached property IsDoubleClicked and set it True for the corresponding TreeViewItem.
And add the trigger for the TreeViewItem's ItemTemplate bound to the property IsDoubleClicked.
Listbox has the style in which itemtemplate consists of expander and inside expander there is a one more listbox, listbox inside the expander has to be accessed. So how to go ahead?
What data does the inner list box contain? Does your outer object contain a list of child objects as a property? If so, bind the inner listbox's ItemsSource to that property.
If you want to access the listbox from code, this is probably what you're looking for: How to: Find DataTemplate-Generated Elements. It shows how to traverse the visual tree to find the generated elements. Using the visual tree is not a good solution usually though, so consider using data binding instead if at all possible.
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.
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.
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.