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

Adding new DataBound items

19 Answers 346 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Paul Gallen
Top achievements
Rank 1
Paul Gallen asked on 23 Feb 2009, 11:39 AM
Hi,


I have a RadTreeView bound to my datasource and everything is working fine, however, I am having trouble when adding a new object to the underlying databound  collection, your documentation does not seem to cover this scenario in depth. What I would like to achieve is this:-

Each time the user right clicks on a treeviewitem a dynamic context menu is built and displayed. (it has to be a dynamic context menu because each node represents a particular business event)

On selection of a menu item , a new node is added to the tree , brought into focus and in edit mode.

I require a reference to the treeviewitem each time the user selects a node (I am a bit confused why the SelectionChanged event does not pass me back a reference to the treeviewitem)

    <DockPanel x:Name="dp" LastChildFill="True" > 
        <DockPanel.Resources> 
           <ContextMenu x:Key="contextMenu">  
            </ContextMenu> 
            <Style TargetType="telerik:RadTreeViewItem" x:Key="itemStyle">  
                <Setter Property="ContextMenuService.ContextMenu" Value="{StaticResource contextMenu}" /> 
            </Style> 
            <CollectionViewSource x:Key="cvs" /> 
              
            <LocalF:GetHBaseListConverter x:Key="GetHBaseListConverter"/>  
 
            <HierarchicalDataTemplate  DataType="{x:Type LocalModel:BaseListHierarchy}" ItemsSource="{Binding Converter={StaticResource GetHBaseListConverter}}">  
                <StackPanel Name="Node" Orientation="Horizontal">  
              
                    <Image Name="imgIcon" Width="20" Height="20" Stretch="Fill" /> 
                    <TextBlock Name="txtNode"   Text="{Binding Name}"  Margin="5,0,0,0" MouseDown="txtNode_MouseDown" /> 
 
                
                </StackPanel> 
                <HierarchicalDataTemplate.Triggers> 
                     
                   <DataTrigger Binding="{Binding IsFolder}" Value="True">  
                            <Setter TargetName="imgIcon" Property="Image.Source" Value="../../Images/folder.png" /> 
                    </DataTrigger> 
                    <DataTrigger Binding="{Binding IsFolder}" Value="False">  
                        <Setter TargetName="imgIcon" Property="Image.Source" Value="../../Images/diskdrive.png" /> 
                    </DataTrigger> 
                    
                </HierarchicalDataTemplate.Triggers> 
            </HierarchicalDataTemplate> 
             
                 
        </DockPanel.Resources> 
          
        <telerik:RadTreeView ItemsSource="{Binding}"   IsDragDropEnabled="True"  Edited="trvListEvents_Edited"    DataContext="{Binding Source={StaticResource cvs }}"   Name="trvListEvents"  Selected="trvListEvents_Selected"    > 
              
        </telerik:RadTreeView> 
             
    </DockPanel> 

Thanks

P

19 Answers, 1 is accepted

Sort by
0
Paul Gallen
Top achievements
Rank 1
answered on 23 Feb 2009, 12:52 PM
HI


OK, I am having  some success. I have created a dynamic context menu and also added a handler to the treeview selected event so I can get at the current treeview item (sorry I was looking at the SelectedChanged event which does not give me the treeviewitem through the SelectionChangedEventArgs).

Now, on the context menu click event I add a new object to my collection. Since I use a HierarchicalDataTemplate with a binding converter, the only way I can get my new item to show in the treeview is to refresh my data source. (is there a more efficent way of doing this?)  What I require at this point is to park the treeview to the new radtreeviewitem and beginEdit, however, inspecting the current treeviewitem's properties HasItems returns false. I think this is because the treeview has been rebound from my last current treeview item ?)

Can you help

Thanks

P


0
Paul Gallen
Top achievements
Rank 1
answered on 24 Feb 2009, 10:23 AM
Guys

Any movement on this. I am getting pushed for time....

Thanks


P
0
Bobi
Telerik team
answered on 26 Feb 2009, 09:46 AM
Hello Paul,

Can you please send us sample code that demonstrates your issue so that we can take a look?

Best wishes,
Boryana
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Paul Gallen
Top achievements
Rank 1
answered on 26 Feb 2009, 11:38 AM
Hi Boryana

Thanks for getting back to me

This is not an issue. I just require a way of manipulating the WPF RadTreeView for my requirements...

They are;

The RadTreeView is databound
Right click on a treevieitem to add a new  item
Once the item has been added  (to the underlying datasource) -the new Treeviewitem (node) must be selected and in edit mode.

Thanks

P
0
Bobi
Telerik team
answered on 27 Feb 2009, 05:18 PM
Hi Paul Gallen,

I suggest that you try the following:

1. Add treeview with datasource for example:

<Telerik:RadTreeView IsDragDropEnabled="True" Name="tree" MouseRightButtonDown="t_MouseRightButtonDown"
                ItemsSource="{Binding Path=Items, ElementName=window}"
                ItemTemplate="{StaticResource NodeTemplate}" ItemContainerStyle="{StaticResource TreeViewItemStyle}">
        </Telerik:RadTreeView>

2. In the code behind:

In the MouseRightButtonDown add the following:

private void t_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            //the treeview is bound to a colection namen Items
            Item i = new Item("Test1");
            this.Items.Add(i);
              if (tree.ItemContainerGenerator.Status ==GeneratorStatus.ContainersGenerated)
            {
                RadTreeViewItem item = tree.ItemContainerGenerator.ContainerFromItem(i) as        RadTreeViewItem;
                item.BeginEdit();
              }
        }

I hope that this will help you in developing your application.

Best wishes,
Boryana
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Paul Gallen
Top achievements
Rank 1
answered on 02 Mar 2009, 10:29 AM
Hi Boryana,

Thanks for the update.

I am unable to get your solution to work, the [RadTreeViewItem item = tree.ItemContainerGenerator.ContainerFromItem(i) as        RadTreeViewItem;] returns null. As you can see from my initial post is that I am using a HierarchicalDataTemplate with a Binding Converter, this seems to be a standard WPF design pattern for binding to a Hierarchical data source, therefore:- In sort, the treeview item would not have been generated yet, because the node that was added is a child node. The example you gave me works because it is a 'flattened' list



Could you please provide an example of  adding new data bound items in this manor. Since the lack of documentation, the example that you will provide will help the rest of the community

Thanks

P
0
Bobi
Telerik team
answered on 05 Mar 2009, 08:04 AM
Hello Paul Gallen,

You can try the following:

1. Add the following code to the application constructor:
 this.tree.ItemContainerGenerator.StatusChanged += new EventHandler(ItemContainerGenerator_StatusChanged);

2. In the event handler add the following:
void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
        {
            if ((sender as ItemContainerGenerator).Status == GeneratorStatus.ContainersGenerated)
            {
                RadTreeViewItem item = tree.ItemContainerGenerator.ContainerFromItem(this.currentItem) as RadTreeViewItem;
                if (item != null)
                {
                    item.Loaded += new RoutedEventHandler(item_Loaded);
                }
            } 
        }
3. In the item_Loaded:
private void item_Loaded(object sender, RoutedEventArgs e)
        {
            (sender as RadTreeViewItem).BeginEdit();
        }


4.Note:  currentItem is an instance of the newly added item to the items source of the treeview . For example:

private void Add_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            currentItem = new CustomItem("Test1");
            this.CustomItemsData.Add(currentItem);
        }

I hope that this answers your question.

Regards,
Boryana
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Paul Gallen
Top achievements
Rank 1
answered on 05 Mar 2009, 11:13 AM
HI Boryana 


It seems that  I have to invoke a refresh on my datasource once I have added a new data item to my bound collection, in order to get the ItemContainerGenerator_StatusChanged to fire. In your latest example you demonstated that you do not have to do this.

If I did not refresh my datasource no treeview events would fire.

Therefore when invoking a refresh, although the bedinEdit has been called (from item_Loaded sub ), the tree is rebuilt as normal and NOT parked at the new item.

What type of collection are you using?
can you send me a complete example?

Thanks


P


0
Paul Gallen
Top achievements
Rank 1
answered on 05 Mar 2009, 02:49 PM
Hi Boryana,

To continue on from my last post, I have changed my datasource from a list to an observable collection, therefore, I do not require to refresh my datasource. However in your example you are still adding your item at at the root level like so:-

private void Add_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            currentItem = new CustomItem("Test1");
            this.CustomItemsData.Add(currentItem);
        }

with my hierarchy, once the roots nodes have been created I will be adding a new item to the selected node, in code, this is achieved by setting a reference to the new item's parent:

ChildObject.Parent = RootObject

Again I think you will have to send me a complete example for my requirements.

Thanks

P


0
Bobi
Telerik team
answered on 08 Mar 2009, 01:53 PM
Hi Paul Gallen,

Here is the code of the complete example:
1.Window1.xaml:
<Window x:Class="WPF_Tests.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:Telerik="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Navigation"
    Title="Window1" x:Name="window" Height="300" Width="300">
    <Window.Resources>
    <HierarchicalDataTemplate x:Key="NodeTemplate" ItemsSource="{Binding Path=Items}">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Path=Header}" />
        </StackPanel>
    </HierarchicalDataTemplate>
        <Style TargetType="Telerik:RadTreeViewItem" x:Key="TreeViewItemStyle">
            <Setter Property="IsExpanded" Value="True"></Setter>
        </Style>
    </Window.Resources>
    <Grid>
        <Telerik:RadTreeView IsDragDropEnabled="True" Name="tree" MouseRightButtonDown="t_MouseRightButtonDown"
                ItemsSource="{Binding Path=Items, ElementName=window}" ItemPrepared="tree_ItemPrepared" IsEditable="True"
                ItemTemplate="{StaticResource NodeTemplate}" ItemContainerStyle="{StaticResource TreeViewItemStyle}">
            <Telerik:RadTreeView.ContextMenu>
                <ContextMenu x:Name="menu" Placement="Absolute" Visibility="Collapsed">
                    <TextBlock Text="Select" />
                    <TextBlock Text="Add" x:Name="Add" MouseLeftButtonDown="Add_MouseLeftButtonDown" />
                </ContextMenu>
            </Telerik:RadTreeView.ContextMenu>
        </Telerik:RadTreeView>
    </Grid>
</Window>
2.Window1.xaml.cs
    public partial class Window1 : Window
    {
        public ObservableCollection<Item> CustomItems
        {
            get { return (ObservableCollection<Item>)GetValue(ItemsProperty); }
            set { SetValue(ItemsProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Items.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ItemsProperty =
            DependencyProperty.Register("Items", typeof(ObservableCollection<Item>), typeof(Window1));

        public Window1()
        {
            InitializeComponent();

            CustomItems = new ObservableCollection<Item>();
            CustomItems.Add(new Item("Item 1"));
            CustomItems.Add(new Item("Item 2"));
            CustomItems.Add(new Item("Item 3"));
            this.tree.ItemContainerGenerator.StatusChanged += new EventHandler(ItemContainerGenerator_StatusChanged);
        }

        void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
        {
            if ((sender as ItemContainerGenerator).Status == GeneratorStatus.ContainersGenerated)
            {
                RadTreeViewItem item = tree.ItemContainerGenerator.ContainerFromItem(this.currentItem) as RadTreeViewItem;
                if (item != null)
                {
                    item.Loaded += new RoutedEventHandler(item_Loaded);
                }
            } 
        }

        void item_Loaded(object sender, RoutedEventArgs e)
        {
            (sender as RadTreeViewItem).BeginEdit();
        }

       
        private void t_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.menu.Visibility = Visibility.Visible;
        }

        private void tree_ItemPrepared(object sender, RadTreeViewItemPreparedEventArgs e)
        {
            RadTreeViewItem currentItem = this.tree.ContainerFromItemRecursive(e.PreparedItem);
            if(currentItem != null)
            currentItem.BeginEdit();
        }

        private Item currentItem;
        private void Add_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            currentItem = new Item("Test1");
            this.CustomItems.Add(currentItem);
        }
    }

    public class Item
    {
        public string Header { get; set; }
        public ObservableCollection<Item> Items { get; set; }

        public Item(string header)
        {
            Header = header;
            Items = new ObservableCollection<Item>();
        }
        public Item(string header,ObservableCollection<Item> Items)
        {
            Header = header;
            Items = new ObservableCollection<Item>();
        }
    }

Best wishes,
Boryana
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Paul Gallen
Top achievements
Rank 1
answered on 09 Mar 2009, 09:57 AM
Thanks

Could you zip this project for me

P
0
Bobi
Telerik team
answered on 13 Mar 2009, 08:04 AM
Hi Paul,

Excuse me for the late response. Please find attached the example project.

Sincerely yours,
Boryana
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Paul Gallen
Top achievements
Rank 1
answered on 07 May 2009, 02:59 PM
Hey long time no feedback from me,


Finally got a project so I can use the radtreeview. Your example that you have attached in the last thread still does not work as expected; using your example it only add nodes to the root level and NOT on the selected node, Is this at all possible? 

To recap my requirement is:-

The RadTreeView is databound
Right click on a treevieitem to add a new  item
Once the item has been added  (to the underlying datasource) -the new Treeviewitem (node) must be selected and in edit mode.
The RadTreeView is databound

All of the above works fine in your attached example, however it does not deal with adding a node on a node.

Thanks

P
0
Miroslav
Telerik team
answered on 08 May 2009, 03:00 PM
Hi Paul Gallen,

I updated the example so that it behaves as you expect now. Please note that in a real-world application you will most probably use Commands that will be assigned to the MenuItems.

Also the ViewModel may be richer and allow more thing to be done with bindings.

Regards,
Miroslav
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Paul Gallen
Top achievements
Rank 1
answered on 08 May 2009, 03:23 PM
Thanks Miroslav

This is just the ticket, great...


P
0
Paul Gallen
Top achievements
Rank 1
answered on 05 Jun 2009, 02:51 PM
May have spoken to soon,

In your example that was attached, I have noticed the following behavior:

Right click on your top node to create a new item... fine
Right click on your top node again to create a new item... the node does not go into edit mode

It appears that it only goes into edit mode, if the node is a leaf, i.e these are no nodes below the current node.

I am experiencing the same problem in my project, I really need this fixed, can you give me a full working example


P




0
Paul Gallen
Top achievements
Rank 1
answered on 09 Jun 2009, 09:39 AM
Guys

can you help? I am really getting pushed for time.


Thanks

P


0
Kiril Stanoev
Telerik team
answered on 09 Jun 2009, 10:17 AM
Hi Paul,

Thank you very much for pointing this strange behavior.
The problem is that the visual tree of the item we are trying to edit is still not ready.
An easy fix to this is to decrease the DispatcherPriority of the dispatcher that is calling the BeginEdit method.
Therefore the treeView_ItemPrepared event handler should look something like this:

void treeView_ItemPrepared(object sender, RadTreeViewItemPreparedEventArgs e) 
    var treeViewItem = e.PreparedItem; 
    var item = treeViewItem.DataContext as OrganisationModel; 
 
    // You may want to mark the newly added item in a different way. 
    if (item.OrganisationName.Equals("New Organisation")) 
    { 
        treeViewItem.Dispatcher.BeginInvoke(new Action(() => 
        { 
            treeViewItem.BeginEdit(); 
            treeViewItem.Focus(); 
        }), System.Windows.Threading.DispatcherPriority.ContextIdle); 
    } 

I have attached the sample project with the latest dlls.
Give it a try and let us know how it works out for you.

All the best,
Kiril Stanoev
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Paul Gallen
Top achievements
Rank 1
answered on 09 Jun 2009, 02:47 PM
Well Done

It works pefectly.


Many thanks


P


Now onto errors when deleting, but that’s another thread ;)


Tags
TreeView
Asked by
Paul Gallen
Top achievements
Rank 1
Answers by
Paul Gallen
Top achievements
Rank 1
Bobi
Telerik team
Miroslav
Telerik team
Kiril Stanoev
Telerik team
Share this question
or