Loading 20000 children under a node kills the app for a long period of time.

5 posts, 0 answers
  1. Andy
    Andy avatar
    5 posts
    Member since:
    Jul 2010

    Posted 24 Jul 2010 Link to this post

    I'm trying to figure this out (new rad control user, LOVE IT!!) but it takes FOREVER for the tree to load. My WCF service comes back almost instantly with 20000 records of data and loading that into the tree just seems to hang for minutes at end. Once loaded, they scroll great. So I know virtualization is working. How can I speed up the loading? It's blocking the main thread which makes the user think the webpage has crashed.

    Here is my tree view + child item which is bound to the source. The source is an ObservableCollection.

     

    <

     

     

    telerik:RadTreeView Grid.Row="1" x:Name="allTopicsReportTreeview" IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling">

     

        <

     

     

    telerik:RadTreeViewItem Header="Unreviewed" ItemsSource="{Binding CurrentReviewProject.TopicsReport.TopicsUnreviewed}" DisplayMemberPath="Title" IsExpanded="False">

     

  2. Andy
    Andy avatar
    5 posts
    Member since:
    Jul 2010

    Posted 26 Jul 2010 Link to this post

    Here is the class properties I'm binding to on the treeview. The class itself isn't bound to the tree, it is the datacontext of the layoutroot though. The treeview has childnodes each one bound to the ObservableCollection of the class.

    public class TopicsViewModel : PropertyChangedNotifier
        {
            #region Commands
            public Commands.ActionDelegateCommand RefreshCommand { get; set; }
            #endregion
     
            #region Fields
            private bool _isLoading;
            private int _projectId;
            private int _userId;
            #endregion
     
            #region Constructors
            public TopicsViewModel(int projectId, int userId)
            {
                RefreshCommand = new Commands.ActionDelegateCommand(refresh);
                _projectId = projectId;
                _userId = userId;
     
                Topics = new ObservableCollection<SimpleTopicStatus>();
                TopicsActiveTasks = new ObservableCollection<SimpleTopicStatus>();
                TopicsSignedOffActiveTasks = new ObservableCollection<SimpleTopicStatus>();
                TopicsUnreviewed = new ObservableCollection<SimpleTopicStatus>();
                TopicsProposedTasks = new ObservableCollection<SimpleTopicStatus>();
                TopicsPendingSignOff = new ObservableCollection<SimpleTopicStatus>();
                TopicsCompleted = new ObservableCollection<SimpleTopicStatus>();
                TopicsTasksAlert = new ObservableCollection<SimpleTopicStatus>();
            }
            #endregion
     
            #region Dependency Properties
            #endregion
     
            #region Properties
            // All topics
            public ObservableCollection<SimpleTopicStatus> Topics { get; set; }
     
            // not signed off - !isClosed !isNew !isOwnerAlert = In progress
            public ObservableCollection<SimpleTopicStatus> TopicsActiveTasks { get; set; }
     
            // signed off - !isClosed !isNew !isOwnerAlert = In Progress
            public ObservableCollection<SimpleTopicStatus> TopicsSignedOffActiveTasks { get; set; }
                     
            // not signed off - 0 tasks
            public ObservableCollection<SimpleTopicStatus> TopicsUnreviewed { get; set; }
             
            // not signed off OR signed off - isNew
            public ObservableCollection<SimpleTopicStatus> TopicsProposedTasks { get; set; }
             
            // not signed off - isClosed
            public ObservableCollection<SimpleTopicStatus> TopicsPendingSignOff { get; set; }
     
            // signed off - isClosed  OR  signed off 0 tasks
            public ObservableCollection<SimpleTopicStatus> TopicsCompleted { get; set; }
     
            // not signed off OR signed off - isOwnerAlert
            public ObservableCollection<SimpleTopicStatus> TopicsTasksAlert { get; set; }
     
            public bool IsLoading { get { return _isLoading; } set { _isLoading = value; OnPropertyChanged("IsLoading"); } }
            public int UserId { get { return _userId; } set { _userId = value; OnPropertyChanged("UserId"); } }
            #endregion
     
            #region Methods
            private void refresh()
            {
                if (!_isLoading)
                {
                    Topics.Clear();                                 // All topics
                    TopicsActiveTasks.Clear();                      // not signed off - !isClosed !isNew !isOwnerAlert = In progress
                    TopicsSignedOffActiveTasks.Clear();             // signed off - !isClosed !isNew !isOwnerAlert = In Progress
                    TopicsUnreviewed.Clear();                       // not signed off - 0 tasks
                    TopicsProposedTasks.Clear();                    // not signed off OR signed off - isNew
                    TopicsPendingSignOff.Clear();                   // not signed off - isClosed
                    TopicsCompleted.Clear();                        // signed off - isClosed  OR  signed off 0 tasks
                    TopicsTasksAlert.Clear();                       // not signed off OR signed off - isOwnerAlert
     
                    IsLoading = true;
     
                    ReportingClient.Execute(client =>
                    {
                        client.Topics_GetStatusCompleted += (sender, e) =>
                        {
                            foreach (var item in e.Result)
                            {
                                Topics.Add(item);
     
                                // Check the data coming back to figure out which bucket it will go into
                                if (item.Tasks > 0)
                                {
                                    if (item.SignedOff == false)
                                    {
                                        if (item.TasksNew > 0)
                                            TopicsProposedTasks.Add(item);
     
                                        else if (item.TasksClosed > 0)
                                            TopicsPendingSignOff.Add(item);
     
                                        else if (item.TasksOwnerAlert > 0)
                                            TopicsTasksAlert.Add(item);
     
                                        else
                                            TopicsActiveTasks.Add(item);
                                    }
                                    else
                                    {
                                        if (item.TasksNew > 0)
                                            TopicsProposedTasks.Add(item);
     
                                        else if (item.TasksClosed > 0)
                                            TopicsCompleted.Add(item);
     
                                        else if (item.TasksOwnerAlert > 0)
                                            TopicsTasksAlert.Add(item);
     
                                        else
                                            TopicsSignedOffActiveTasks.Add(item);
                                    }
     
                                }
                                else
                                {
                                    if (item.SignedOff)
                                        TopicsCompleted.Add(item);
                                    else
                                        TopicsUnreviewed.Add(item);
                                }
                            }
     
                            IsLoading = false;
                        };
     
                        if (_userId == 0)
                            client.Topics_GetStatusAsync(_projectId, false, 0);
                        else
                            client.Topics_GetStatusAsync(_projectId, true, _userId);
     
                        client.CloseAsync();
                    });
                }
            }
            #endregion
        }
  3. Andy
    Andy avatar
    5 posts
    Member since:
    Jul 2010

    Posted 27 Jul 2010 Link to this post

    Still unsure what to do. I bind a listbox to the same source, with a virtualizingStackPanel as the ItemsPanel, and it works flawlessly.
  4. Andy
    Andy avatar
    5 posts
    Member since:
    Jul 2010

    Posted 29 Jul 2010 Link to this post

    Well I decided to scrap my design and use a different way to present the data to the user.
  5. Tina Stancheva
    Admin
    Tina Stancheva avatar
    3299 posts

    Posted 29 Jul 2010 Link to this post

    Hello Andy,

    Please accept my apology for the delayed response.

    Unfortunately the RadTreeView doesn't support scenarios where its Items are populated both in XAML and through data binding like in your case. This is perhaps the main reason for the issue. Therefore I wanted to ask you to try and databind the ItemsSource collection of the whole RadTreeView to the data from the WCF service. You can take a look at the performance demo of the RadTreeView.

    Give it a try and let us know if you are still experiencing issues. However, if this doesn't help in solving the issue, if you can send us a sample project reproducing it, we will be more than happy to further investigate it.

    Kind regards,
    Tina Stancheva
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Back to Top