This is a migrated thread and some comments may be shown as answers.

Creating new TreeView nodes

11 Answers 231 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Jakub
Top achievements
Rank 1
Jakub asked on 12 Sep 2009, 12:34 PM

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 { setget; } // The child folders are stored here  
  public string Title { setget; } // The display name  
  public int Id { setget; }  

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 == nullreturn// 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

Sort by
0
Accepted
Miroslav
Telerik team
answered on 12 Sep 2009, 12:52 PM
Hello Jakub,

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.
0
Jakub
Top achievements
Rank 1
answered on 12 Sep 2009, 01:12 PM
Thanks a lot Miroslav!
0
Frank
Top achievements
Rank 1
answered on 18 Sep 2009, 10:41 PM

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?

0
Miroslav
Telerik team
answered on 23 Sep 2009, 09:08 AM
Hi Frank,

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.
0
Frank
Top achievements
Rank 1
answered on 24 Sep 2009, 02:01 PM

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 ?

0
Valentin.Stoychev
Telerik team
answered on 27 Sep 2009, 04:20 PM
Hello Frank,

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.
0
Frank
Top achievements
Rank 1
answered on 20 Oct 2009, 09:40 PM

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.

0
Bobi
Telerik team
answered on 23 Oct 2009, 07:20 AM
Hello Frank,

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.
0
Frank
Top achievements
Rank 1
answered on 29 Oct 2009, 08:12 PM
This works great. Thank you.
0
Kabs Hussain
Top achievements
Rank 1
answered on 10 Nov 2009, 12:49 PM
Hi,
  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.
0
Bobi
Telerik team
answered on 13 Nov 2009, 01:04 PM
Hello Kabs Hussain,

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.
Tags
TreeView
Asked by
Jakub
Top achievements
Rank 1
Answers by
Miroslav
Telerik team
Jakub
Top achievements
Rank 1
Frank
Top achievements
Rank 1
Valentin.Stoychev
Telerik team
Bobi
Telerik team
Kabs Hussain
Top achievements
Rank 1
Share this question
or