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

How do I get the RadTreeViewItem if I'm using HierarchicalDataTemplate?

7 Answers 619 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Luis
Top achievements
Rank 1
Luis asked on 10 Apr 2009, 06:28 PM
I have a RadTreeView with HierarchicalDataTemplate as follows:

<HierarchicalDataTemplate DataType="Category" ItemsSource="{Binding XPath=Category}"
   <TextBlock x:Name="tbCategoryName" Text="{Binding XPath=@Name}" MouseRightButtonUp="tbCategoryName_MouseRightButtonUp" 
                           MouseDown="tbCategoryName_MouseDown"
   </TextBlock> 
</HierarchicalDataTemplate> 

I need access to the RadTreeViewItem so that I can call methods and properties such as BeginEdit, ExpandAll, and IsExpanded.
This is my RadTreeView declaration:

        <telerik:RadTreeView ItemsSource="{Binding Source={StaticResource CategoriesXML}}" Margin="105,64,0,0"  
                             Name="tvOntology" HorizontalAlignment="Left" VerticalAlignment="Top" Width="200" 
                             IsEditable="True" IsEnabled="True" IsExpandOnDblClickEnabled="False"  
                             IsExpandOnSingleClickEnabled="True"
        </telerik:RadTreeView> 
 
It works fine but I'm not able to get the RadTreeViewItem. Could someone tell me how, please?

7 Answers, 1 is accepted

Sort by
0
Mike
Top achievements
Rank 1
answered on 10 Apr 2009, 10:46 PM
Hi Luis

from where do you need the access? if it is from your mouselistener then you may try this:

object item = myTreeView.SelectedItem;
RadTreeViewItem tvi = myTreeView.ContainerFromItemRecursive(item); 

Greez Mike


0
Luis
Top achievements
Rank 1
answered on 12 Apr 2009, 07:54 PM
I was trying to access it from other events. I managed to do it with ChildrenOfType<RadTreeViewItem>(). Your post did help though, thanks.
0
Luis
Top achievements
Rank 1
answered on 13 Apr 2009, 01:23 AM
I'm still having a hard time getting the RadTreeViewItem's.

myTreeView.ChildrenOfType<RadTreeViewItem>(); only returns the root item and I can't get any further by any means.

Is there a way to itereate through the RadTreeViewItem's?

Thanks.
0
Accepted
Ivan
Telerik team
answered on 14 Apr 2009, 08:18 AM
Hi Luis,

Please preview the How do I get the RadTreeViewItem article where accessing the RadTreeViewItem is demonstrated.

Hope this information helps.

All the best,
Ivan
the Telerik team

Check out Telerik Trainer , the state of the art learning tool for Telerik products.
0
Tim
Top achievements
Rank 1
answered on 06 Aug 2009, 05:35 PM
foreach (RadTreeViewItem item in Renderer.ChildrenOfType<RadTreeViewItem>()) 
    // item is an in-order traversal of the tree, but only those nodes 
    // which have been previously or explicitly visited. 
 





Given the above, I want to compare each (item.Item as MyObject).Property to some other object's property.  If I have not yet expanded a given node, it's children do not show up.  How come?  If I expand them first (and collapse them) then they appear in the loop.

It must have to do with when the items are prepared.  The problem is that I am trying to attach a double click from a RadGridView's row to a specific item in the tree, but if that node has not yet been opened, I can't find it (I wish to keep the navigation in sync regardless of the double-click-in-a-Grid or click-on-a-tree-node method chosen).

Can I force the tree to always pre-prepare items?  Is there a better way?  Can I ask each item to prepare its children?  I doin't want to expand the whole tree for sure.

Thx,
Tim

0
Ivan
Telerik team
answered on 12 Aug 2009, 07:58 AM
Hi Luis,

The virtualization (i.e. creation / non-creation) of the item containers is by design - this is the feature of the Silverlight Framework. As a small demonstration we prepared (and attached here) an example. Below is its description:

    Attached example file: ContainerFromItemRecursive.zip

In order to get container below the first level you can try the RadTreeView.ContainerFromItemRecursive() method. But please be aware of the following. If your tree items are data bound (via ItemsSource) some of their containers (RadTreeViewItem) appeared not constructed (until you expand their branches). For example in the attached project there is a three level tree. After the page loads you can see only first level items and really only their containers are constructed. If you click the "Select my Favorite Item" nothing will happens (until you expand the tree). After you expand the tree (press the "Expand the Tree" button) you can get the container of the "Favorite Item" (the item at the "bottom" of the tree).

Note: You mentioned comparison of items of MyObject type. Because of this I had realized you want to deal with the data items (but not with items' containers). In this case you can get them via your data source. But once again accessing to the item's container depends on its existence (i.e. is it created).


As I found the other aspect from your post is related to the SelectedItem synchronization. Below we will try to explain the case:

    Attached example file: Binding to SelectedItem.zip

Currently the SelectedValue, the SelectedItem and the SelectedItems properties have only getters. Even more the SelectedItem returns the first item from the SelectedItems collection. Because of this you can not bind to it. But if you try the attached example you will (probably) find a way to workaround the case. Below is a short description of the workaround:
  • In general there are two synchronized RadTreeViews. For more information please visit the following blog post: Simulating IsSynchronizedWithCurrentItem in Silverlight.
     
  • In order to accomplish SelectedItem binding you have to add some additional extensions:
    1. Add some extensions classes to your application as shown in the sample application.
       
    2. Add an additional attached property:
       
      public static readonly DependencyProperty IsSynchronizedWithCurrentItemProperty = 
          DependencyProperty.RegisterAttached("IsSynchronizedWithCurrentItem"
              typeof(bool), 
              typeof(SelectorExtension), 
              new PropertyMetadata(false, (s, e) => 
          var control = s as RadTreeView; 
          if (control == null
          { 
              return
          } 
          if (control.ItemsSource != null
          { 
              if ((bool)e.NewValue) 
              { 
                  SetBinding(control, control.ItemsSource as IObservableCollectionEx); 
              } 
              return
          } 
          if ((bool)e.NewValue) 
          { 
              control.SelectionChanged += new SelectionChangedEventHandler(control_SelectionChanged); 
              _selectors.Add(control); 
          } 
          else 
          { 
              if (_selectors.Contains(control)) 
              { 
                  _selectors.Remove(control); 
              } 
          } 
      })); 
       
    3. Subscribe to SelectionChanged:
       
      control.SelectionChanged += 
          new SelectionChangedEventHandler(control_SelectionChanged); 
       
    4. Add the desired code in the SelectionChanged  handler:
       
      static void control_SelectionChanged(object sender, Telerik.Windows.Controls.SelectionChangedEventArgs e) 
          ... 
          //Add the desired functionality here 
          SetBinding(control, source.SelectedObject); 
          ... 
       
      where:
       
      private static void SetBinding(RadTreeView control, object source) 
          if (control.ItemContainerGenerator.ContainerFromItem(source) != null
          { 
              (control.ItemContainerGenerator.ContainerFromItem(source) as RadTreeViewItem).IsSelected = true
          } 
       
    5. After you have done all explained in the previous steps set the attached property in XAML:
       
      <telerik:RadTreeView 
          ItemTemplate="{StaticResource DataTemplate1}" 
          ItemsSource="{Binding Items}" 
          local:SelectorExtension.IsSynchronizedWithCurrentItem="True" /> 
       



As a force creation of tree items you can rely on the ExpandAll method (preview the first example), but it still expands the tree visually. Recently we implement two new methods that may help you to find an appropriate solution: GetItemByPath and ExpandItemByPath. We advise you to try them too.

Sincerely yours,
Ivan
the Telerik team

Check out Telerik Trainer , the state of the art learning tool for Telerik products.
0
Tim
Top achievements
Rank 1
answered on 14 Aug 2009, 02:28 PM
Ivan,

ExpandItemByPath does the trick.  Luckily I have the container hierarchy handy so I can specify the node I want and its ancestors.

Tim
Tags
TreeView
Asked by
Luis
Top achievements
Rank 1
Answers by
Mike
Top achievements
Rank 1
Luis
Top achievements
Rank 1
Ivan
Telerik team
Tim
Top achievements
Rank 1
Share this question
or