Treeview loadondemand with MVVM

10 posts, 1 answers
  1. luc
    luc avatar
    24 posts
    Member since:
    Aug 2011

    Posted 24 Jun 2013 Link to this post

    Hi,

    I have a WPF project with a RadTreeView with loadondemand enabled and i want to be able to add/edit/delete item by a RadControlMenu in a mvvm context.
    The project sample can be found here https://docs.google.com/file/d/0B6ihaOKSuZdBaHpxUVpPZzgzQ00/edit?usp=sharing. (.NET 4.5 with Telererik Controls Q2 2013). The sample load the folder on C drive for loadondemand but NOTHING is implemented when add/rename action are called (only UI).

    1- I have a different behavior between empty/not empty folder. When i set the Expanded property to true in my viewmodel the loadondemand is well fired but when just after i add the new folder in my observablecollection, for empty folder the new folder is not shown (it's like the node is not expanded) and for folder with childs the new folder is well shown. 
       // Expanded = true fire the loadondemand if needed and open the treenode
       if (!this.Expanded) this.Expanded = true;

       // Insert the new newfolder
       // If the folder is empty when added the new folder the node is not show
       // If the folder is not empty, the folder is expanded and the node is show
       FolderWrapper newFolder = new FolderWrapper(new Folder() { Name = "New folder" });
       this._subFolders.Add(newFolder);

    2- Like i want a couple less between my viewmodel and view, i use a event to fire the new folder into my view. I use the ExpandToPendingSelection sample (wpf treeview documentation) to select and bring the item into the view. But I don't found the way to set the item in editmode (even if i use a edittemplate). The item is not selected and the focus is always on treeview.

       ExpandToPendingSelection(path.ToString().Split('.'));

       Dispatcher.BeginInvoke(
        (Action)delegate
       {
        var treeViewItem = treeView.SelectedContainer;

        treeViewItem.IsInEditMode = true;

        // Now we can focus, select, edit the item:
        treeViewItem.Focus();
       });

    3- When I add a new folder in a not expanded folder near the windows bottom and if the childs node fill the window the item is not bring into view.

    Thanks,
    Luc

     

     

  2. Pavel R. Pavlov
    Admin
    Pavel R. Pavlov avatar
    1182 posts

    Posted 27 Jun 2013 Link to this post

    Hello Luc,

    As far as I understand you want to use the LoadOnDemand feature of the RadTreeView control. Furthermore, you  want to bring into the view port, add and edit items at run-time. One possible approach is to use commands in combination with bindings (which you have implemented). You can also bind in TwoWay mode the IsSelected property of the RadTreeViewItems (using a Style) to property defined in your View-Model.

    Regarding your second question, you focus the selected container in your code. Hence, it is expected that  the corresponding RadTreeViewItem is focused. Maybe you expect that the focus should be in the TextBox since the item is in edit mode. In order to do this you will have to make sure that the corresponding RadTreeViewItem is visualized and then set it in edit mode. You can do this be subscribing to the ItemsPrepared event of the RadTreeView control.

    Regarding your last question, it seems that the BringIndexIntoView() method can not visualize hierarchical data. This is why we recommend using the BringPathIntoView() method. You can find an article, explaining how you can implement it here. Furthermore, at the end of the article you can find a link leading to a blog post with additional information about the usage of the method and a runnable project, demonstrating the described approach. Actually, you can achieve your requirements by implementing the LoadOnDemand feature and your custom commands into the demonstrating project.

    I hope this information will help you.

    Regards,
    Pavel R. Pavlov
    Telerik
    TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
    Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
    Sign up for Free application insights >>
  3. UI for WPF is Visual Studio 2017 Ready
  4. luc
    luc avatar
    24 posts
    Member since:
    Aug 2011

    Posted 02 Jul 2013 Link to this post

    Hello,

    It seems that BringPathINtoView don't work with LoadOnDemand enabled, so i try with this post blog. (BringIntoView)
    Unfotunatly this post work only when the tree is not expanded, if i expand a node and choose to add a childern, the ItemPrepared is trigger on the first UpdateLayout and break the sequence to retrieve/select/edit the new item.
    I'm interesting by a blog where we add (programmatically) a new item inside an existing treeviewitem, bring into view, select and edit it. (all of this with a treeview with loadondemand enable).
    Thanks.
    Luc
  5. Pavel R. Pavlov
    Admin
    Pavel R. Pavlov avatar
    1182 posts

    Posted 05 Jul 2013 Link to this post

    Hello Luc,

    I am not sure that I fully understand your scenario. Can you please elaborate more on the steps that you take and the results that you observe in your current implementation. What you have in mind when you say "BringPathINtoView don't work with LoadOnDemand enabled"? Are you saying that the LoadOnDemand event of the RadTreeView control is not invoked or the corresponding item can not be visualized by the BringPathIntoView() method? Please note that it will be best if you can reproduce this behavior in a separate project and send it over. By doing so, we will be able to fully understand your scenario and make a proper suggestion in your case.

    Thank you for your kind cooperation.

    Regards,
    Pavel R. Pavlov
    Telerik
    TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
    Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
    Sign up for Free application insights >>
  6. luc
    luc avatar
    24 posts
    Member since:
    Aug 2011

    Posted 05 Jul 2013 Link to this post

    Hi,

    You can found an application sample here Link
    The project show a treeview with the LoadOnDemand enabled. The list of item is provided by a service class (DriveService), for this project the items are built statically (but in reality the item will be loaded from database).  A wrapper (FolderWrapper) is used for bindings between the model and the view. The objective is to able to add a new item Inside an existing item, bring it to the view, select it and edit it.

    - BringPathIntoView : If you launch the application, set the path to 1.191 (textbox Under the bringpathintoview button) and click on Bringpathintoview button nothing happend. However if you expand the "Item 1", the item 1.191 exists. In fact, i don't expected that it can do well the job, because I don't want raise a loadondemand on each Item to find the correct node.

    - Add a new item : To do that i used this Blog. Launch the application, open the "Item 1", right click on "Item 2" and select Add menu. The Item2 is expanded (like expected Line 107 FolderWrapper), but the new item is not selected. In fact when i run through the treeview with the ExpandToPendingSelection method, the new item is prepared (ItemPrepared) before i reach it, i don't know if it's the reason of my problem to select the item.

    Regards,
    Luc

  7. Tina Stancheva
    Admin
    Tina Stancheva avatar
    3298 posts

    Posted 10 Jul 2013 Link to this post

    Hello Luc,

    Thank you for sharing your solution. However we will need more time to take a closer look at your implementation and advice you how to proceed. I will get back to you tomorrow the latest.

    Regards,
    Tina Stancheva
    Telerik
    TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
    Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
    Sign up for Free application insights >>
  8. Answer
    Tina Stancheva
    Admin
    Tina Stancheva avatar
    3298 posts

    Posted 11 Jul 2013 Link to this post

    Hi Luc,

    When working with the BringIntoView support of the RadTreeView, it is important to prove the path to an item. In your case "1.191" represents the value of the Path property of the item but does not represent the path to that item. The path to that item in fact is "1\1.191". The path to a node in the RadTreeView control consists of the path from the root to the last child in the hierarchy of the node. And as you used the Path property as a path segment (in the definition of the RadTreeView the TextSearch.TextPath is set to Path)  to build the path to Item 191, you need a string that consists of
    • the path segment of Item 1, which is "1",
    • path separator, which by default is "\"
    • the path segment of Item 191, which is 1.191

    It is also important to note that you can't bring into view not-existing items. This means that you need to first load the children of Item 1 and only then try to bring them into view. That does not specifically mean that you have to call the LoadOnDemand() method first by expanding the item. But it means that when you hit the BringPathIntoView button you need to know that Item 191 is defined in the children collection of Item 1. For instance you can add the item in the button click event handler.

    So basically regarding point 1 of your query, if you first load the child items of Item 1, enter "1\1.191" in the TextBox and hit the BringPathIntoView button while Item 1 is collapsed, the button will bring Item 191 into view. However, please note that even though this logic will bring it into view, the item will not be selected unless you make it so.

    Which brings us to your second question regarding adding new item and selecting it whilst using LoadOnDemand. The tutorial you've been using is quite outdated and there is a better approach for this case. Basically, my suggestion is to bind the IsSelected property of the RadTreeViewItems to a Selected property in the ViewModels. In your example this would mean to add a definition of a Selected property in the FolderWrapper class:

    bool _selected;
      /// <summary>
            /// Get or set the selection state
            /// </summary>
            public bool Selected
            {
                get { return _selected; }
                set
                {
                    if (_selected != value)
                    {
                        _selected = value;
                        this.OnPropertyChanged("Selected");
                    }
                }
            }
    Then extend the FolderItemStyle to include a new setter for the IsSelected property:
    <Setter Property="IsSelected" Value="{Binding Path=Selected, Mode=TwoWay}" />

    Finally modify the NewItem() method to set the selected value of the new item to True:
    private void NewItem(object sender)
    {
        ...
        if (!this.Expanded) this.Expanded = true;
        ...
        FolderWrapper wrapper = new FolderWrapper(newFolder);
        wrapper.Selected = true;
        this._subFolders.Add(wrapper);
        ...
    }

    Then you can even remove the Folder_Event logic altogether:
    private void Folder_Event(object path)
    {
        //pendingSelectionPath = new List<string>();
        //pendingSelectionPath.AddRange(path.ToString().Split('.'));
        //ExpandToPendingSelection();
    }
    and still as soon as you add a new item it will be selected when its parent is expanded.

    I'd recommend using the Selected and expanded business properties to control the selected and expanded state of the TreeView nodes wherever possible.

    I hope that information will help you. And if you need further assistance, it will be best to use the support ticketing system as it comes with a guaranteed response time depending on your license type and it also ensures that all questions will reach the respective developers, if needed.

    Regards,
    Tina Stancheva
    Telerik
    TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
    Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
    Sign up for Free application insights >>
  9. luc
    luc avatar
    24 posts
    Member since:
    Aug 2011

    Posted 12 Jul 2013 Link to this post

    Hi,

    Thank you, the BringPathIntoView work well, next time i will do a support ticket. But i have a new question now :)

    I use now the Folder_Event to bring the item into view (because only the view has a reference to treeview), it's work fine when i have few item in my collection not when i have a lot of item. For sample if I expand the Item 1 and do a right click on "Item 23" and select "New", the folder is well expanded, the new item is well created and selected, its well bring into view... but just after all others items in this folder are Prepared and the new item is pushed out the view. I've try to subscribe to some treeview events to Bring the item after all others item prepared but without succes. What's the best way ?

    An updated project can be found here post

    Thanks
  10. luc
    luc avatar
    24 posts
    Member since:
    Aug 2011

    Posted 15 Jul 2013 Link to this post

    Hi,

    The problem is due to animations. If i set the AnimationManager.IsAnimationEnabled to false like explained in this post, it's work.
    Do you have a better solution than disable all animations ?
    Thanks
  11. Tina Stancheva
    Admin
    Tina Stancheva avatar
    3298 posts

    Posted 17 Jul 2013 Link to this post

    Hi Luc,

    As you need to simultaneously load items on demand, add new item and bring it into view - in this scenario the animation will only cause issues.

    Basically as soon as you start expanding an item, the RadTreeView expand animation is automatically triggered and it slows down the expansion of all items. And in your particular case, the BringIntoView method is called before the items are fully expanded thus causing the described behavior. You can definitely workaround it by disabling the TreeView animation. But if you don't want to entirely loose the animations of the control (for instance if you want a sample expand operation to use the built-in expand animation), then a better approach would be to disable the animations only while an item is being brought into view.

    In the last solution you sent you can change the Folder_Event method like so:
    private void Folder_Event(object path)
    {
        AnimationManager.SetIsAnimationEnabled(treeView, false);
        treeView.BringPathIntoView(path.ToString());
        AnimationManager.SetIsAnimationEnabled(treeView, true);
    }

    Regards,
    Tina Stancheva
    Telerik
    TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
    Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
    Sign up for Free application insights >>
Back to Top
UI for WPF is Visual Studio 2017 Ready