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">
4 Answers, 1 is accepted
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 }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