First of all I want to say that you guys at Telerik are doing a wonderful job and I'm really excited about the Silverlight controls. However, I got stuck when working with TreeView and I spent more than an hour looking for a solution with no success.
Here is my scenario:
I want to use the TreeView control to represent an editable structure of folders. There are several buttons ("Delete", Rename" etc.) to perform specific operations. There is also the "Add Child Folder" button that creates a new folder inside the currently selected one. Once a new folder is added, I want to select it and enable the edit mode so the user can choose a name of the new folder.
The whole tree is built using data binding with ObservableCollections. Here is a simplified version of the class that is used to build the hierarchical structure:
public class Folder { |
public ObservableCollection<Folder> Items { set; get; } // The child folders are stored here |
public string Title { set; get; } // The display name |
public int Id { set; get; } |
} |
Almost everything works fine - when I add a new item to the structure of Folder objects, the TreeView is updated thanks to data binding. When I select a TreeView item and press F2, I can edit its name and thus change the Title property of the corresponding Folder object. The "Rename" and "Delete" buttons work fine as well.
However, I find myself unable to create a new item and then enable the edit mode from code-behind. I have read several threads on the forum and I found out that the RadTreeViewItem objects are created asynchronously - and that's the problem...
Here is my method that is called when user clicks the "Add Child Folder" button:
private void AddChild_Click(object sender, System.Windows.RoutedEventArgs e) { | |
if (FoldersTreeView.SelectedItem == null) return; // If no node is selected, return | |
Folder f = new Folder() { Id = 0, Title = "NewFolder" }; // Create a new Folder object | |
((Folder)FoldersTreeView.SelectedItem).Items.Add(f); // Add the newly created folder to the structure | |
// Now find the newly created RadTreeViewItem | |
RadTreeViewItem NewNode = FoldersTreeView.ItemContainerGenerator.ContainerFromItem(f) as RadTreeViewItem; | |
// The following part doesn't work, because NewNode is always null | |
NewNode.IsSelected = true; | |
NewNode.IsInEditMode = true; | |
} |
The code above is wrong and it doesn't work, but it demonstrates my problem. Because TreeView nodes are created asynchronously, I can't select the newly created RadTreeViewItem.
Now the question is: what do I have to do to access a RadTreeViewItem object after it has been created?
Regards,
Jakub Zika
11 Answers, 1 is accepted
Yes, indeed the ItemsControls generate containers for their items asynchronously and this sometimes is a problem. There are things you can do though.
First, this line of your code:
FoldersTreeView.ItemContainerGenerator.ContainerFromItem(f) as RadTreeViewItem;
Will only retrieve containers for the immediate children of the TreeView but not their children (TreeView's descendants).
You can use the ContainerFromItemRescursive method on the TreeView to get a container that has been generated by one of the children.
In your case you can wait or containers to be generated by putting your code in a Dispatcher.BeginInvoke() or by handling the ItemPrapared event of the TreeView and then checking whether a new item has just had its container prepared.
The best way though IMO is to bind the IsInEditMode property of your ViewModel (the class that you bind to). This way you just need to flip a property on your class and not worry about getting the container. The same can be done for the IsSelected proeprty.
To bind this, you need to use ItemContainerBindings here is an example of how to define an ItemContainerBinding:
<telerik:ContainerBindingCollection x:Key="ItemContainerBindings">
<telerik:ContainerBinding PropertyName="IsInEditMode" Binding="{Binding MyIsInEditMode}" />
<telerik:ContainerBinding PropertyName="IsSelected" Binding="{Binding MyIsSelected}" />
</telerik:ContainerBindingCollection>
And this is how you apply them to a template:
<telerik:HierarchicalDataTemplate x:Key="ItemTemplate" ItemsSource="{Binding Children}" telerik:ContainerBinding.ContainerBindings="{StaticResource ItemContainerBindings}" />
Hopefully you will be able to use this to simplify your code,
Miroslav
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
Hello,
We have a similar scenario where we have to add a node from the code behind and immediately set it into the edit mode.
Adding the new item to Observable collection effectively puts the new node to the hierarchy,
but unfortunately setting the new item into the edit mode doesn't seem to work, the ItemEdit Template just doesn't appear.
I have tried to do it both from the ItemPrepared event and through the method recommended in this post.
Any other node in the tree can be set into the edit mode through any of these methods but only not the new one.
Only pressing F2 is working for the new node.
Any ideas?
This is unexpected.
Are you using ItemEditTemplate or ItemEditTemplateSelector?
Can you confirm that the IsInEditMode property is true while the EditTemplate is not visible?
If this is the case, then this most probably is a bug.
I guess that the property may be set too early and the TreeView item does not update its state. As a workaround I can suggest setting the IsInEditMode property only at one place and using a binding or a dispatcher to do so.
You can use a dispatcher in the following way:
Deployment.Current.Dispatcher.BeginInvoke( () => item.IsInEditMode = true);
If you send us a sample project where this happens I will be happy to look at what may be going wrong.
Regards,
Miroslav
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
Thank you Miroslav,
I use ItemEditTemplate , although when looking at this issue I tried to remove it altogether but the behavior was the same - item was not going to the edit mode.
The dispatcher and ContainerBinding were also tried with no success.
When in ItemPrepared event the debugger is showing that the IsInEditMode property of the required node is set to true.
The functionality I have been trying to accomplish is rather simple - add the new item to the collection of children in the business object (works as expected) and set the corresponding node into edit mode right after it was added (doesn’t work for the new node).
I will try to produce the sample project a little later.
Have you tried the above scenario and does it work for you ?
Please try this code:
RadTreeViewItem myNode = new RadTreeViewItem() { Header = "myTest"};
tree1.Items.Add(myNode);
Deployment.Current.Dispatcher.BeginInvoke(() => myNode.IsInEditMode = true);
It is working on our end - please let us know if it works for you too.
We will fix the issue with the next release of the TreeView.
Regards,
Valentin.Stoychev
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
Hello Valentin,
Sorry for the late reply. The deadlines are tight here and I realized that I had to come up with the project to illustrate the problem.
The scenario that I have been talking about is as follows:
The tree is bound to data source which represents the tree hierarchy and is an observable collection of the business objects.
When adding the new business object to an observable collection of children of any business object the new node gets added to the tree which is, of course, as expected.
The problem is that when I try to set the newly added item into the edit mode this unfortunately doesn't work, neither with the ContainerBinding nor setting the isInEditMode property in the ItemPrepared event.
The other issue, which I guess is somehow related to the problem described above,is that the Treeview Selected event is not fired
when the first new child item is added to the node and gets selected.
We had to work around these problems to meet the deadlines.
But still I would be curious to know what your thoughts are.
I have uploaded the test project to the Ticket Center.
Thank you.
Please find attached a sample project that shows how to add new item to the treeview and set it in edit mode. Also you can see that the usage of SelectionChanged event.
I hope that this will help you. Please let us know if you have any other questions or you need some more help. If so please send us some sample code in order to fix it.
Regards,
Boryana
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
I am creating a TreeView dynamically on selectiong of some node from another Treeview.
To create the Treeview I used to following approach.
I took a RadTreeViewItem object. Depending on my business logic I am adding child nodes to it.
Now I am trying to bind this Final RadTreeViewItem objrct to my Treeview Control tvMytreeView using
tvMyTreeview.Itemsource = "created RadTreeViewItem "
This was working fine with Q2 release.
But with Q3 it binds the data but does not diplay any node Header.Means I cann't see the Nodes value.
Moreover it throws some exception when I bring the mouse on the Treeview control.
Note that My treeview is Multiselect Treeview.
A little help will be appreciable.
Thanks,
Kabs.
We were unable to reproduce this issue.
Did you take a look at the "treeview-additemineditmode.zip" example in the same forum thread?
You can also review the online examples:
http://demos.telerik.com/silverlight/#TreeView/DataBinding
If this still does not help you please send us some sample project or explain in more details whet kind of datasource are you using?
Best wishes,
Boryana
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.