Adding new DataBound items

20 posts, 0 answers
  1. Paul Gallen
    Paul Gallen avatar
    156 posts
    Member since:
    Jun 2008

    Posted 23 Feb 2009 Link to this post

    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
  2. Paul Gallen
    Paul Gallen avatar
    156 posts
    Member since:
    Jun 2008

    Posted 23 Feb 2009 Link to this post

    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


  3. Paul Gallen
    Paul Gallen avatar
    156 posts
    Member since:
    Jun 2008

    Posted 24 Feb 2009 Link to this post

    Guys

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

    Thanks


    P
  4. Bobi
    Admin
    Bobi avatar
    513 posts

    Posted 26 Feb 2009 Link to this post

    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.
  5. Paul Gallen
    Paul Gallen avatar
    156 posts
    Member since:
    Jun 2008

    Posted 26 Feb 2009 Link to this post

    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
  6. Bobi
    Admin
    Bobi avatar
    513 posts

    Posted 27 Feb 2009 Link to this post

    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.
  7. Paul Gallen
    Paul Gallen avatar
    156 posts
    Member since:
    Jun 2008

    Posted 02 Mar 2009 Link to this post

    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
  8. Bobi
    Admin
    Bobi avatar
    513 posts

    Posted 05 Mar 2009 Link to this post

    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.
  9. Paul Gallen
    Paul Gallen avatar
    156 posts
    Member since:
    Jun 2008

    Posted 05 Mar 2009 Link to this post

    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


  10. Paul Gallen
    Paul Gallen avatar
    156 posts
    Member since:
    Jun 2008

    Posted 05 Mar 2009 Link to this post

    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


  11. Bobi
    Admin
    Bobi avatar
    513 posts

    Posted 08 Mar 2009 Link to this post

    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.
  12. Paul Gallen
    Paul Gallen avatar
    156 posts
    Member since:
    Jun 2008

    Posted 09 Mar 2009 Link to this post

    Thanks

    Could you zip this project for me

    P
  13. Bobi
    Admin
    Bobi avatar
    513 posts

    Posted 13 Mar 2009 Link to this post

    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.
  14. Paul Gallen
    Paul Gallen avatar
    156 posts
    Member since:
    Jun 2008

    Posted 07 May 2009 Link to this post

    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
  15. Miroslav
    Admin
    Miroslav avatar
    922 posts

    Posted 08 May 2009 Link to this post

    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.
  16. Paul Gallen
    Paul Gallen avatar
    156 posts
    Member since:
    Jun 2008

    Posted 08 May 2009 Link to this post

    Thanks Miroslav

    This is just the ticket, great...


    P
  17. Paul Gallen
    Paul Gallen avatar
    156 posts
    Member since:
    Jun 2008

    Posted 05 Jun 2009 Link to this post

    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




  18. Paul Gallen
    Paul Gallen avatar
    156 posts
    Member since:
    Jun 2008

    Posted 09 Jun 2009 Link to this post

    Guys

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


    Thanks

    P


  19. Kiril Stanoev
    Admin
    Kiril Stanoev avatar
    1512 posts

    Posted 09 Jun 2009 Link to this post

    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.
  20. Paul Gallen
    Paul Gallen avatar
    156 posts
    Member since:
    Jun 2008

    Posted 09 Jun 2009 Link to this post

    Well Done

    It works pefectly.


    Many thanks


    P


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


Back to Top