Load on Demand

Load On Demand feature allows you to delay the population of RadTreeView and load subitems only when they’re requested, thus saving computing resources and improving the initial performance of your app.

The Load on Demand mechanism is implemented in such a way that as soon as the end-user tries to expand an item, the treeview receives a notification that a load on demand operation is requested and a busy indicator is displayed for the respective item. When the requested items are loaded, and the operation is marked as finished, the busy indicator is hidden and the items are visualized in the TreeView.

In order to enable the load on demand feature, you would need to utilize the LoadOnDemand command of RadTreeView as demonstrated in the example below:

First, let's create a sample Category class which represents the root items of the TreeView and holds its subitems inside its Children property:

public class Category : NotifyPropertyChangedBase
{       
    public string Name { get; set; }

    ObservableCollection<string> children;
    public ObservableCollection<string> Children
    {
        get
        {
            return this.children;
        }
        set
        {
            if (this.children != value)
            {
                this.children = value;
                this.OnPropertyChanged();
            }
        }
    }       
}

Then, create a ViewModel with a sample Source property which contains the root items of the TreeView. You would also need to create a Command for handling the load on demand scenario.

public class ViewModel : NotifyPropertyChangedBase
{
    public ObservableCollection<Category> Source { get; set; }
    public ICommand LoadOnDemandCommand
    {
        get; set;
    }
    public ViewModel()
    {
        this.Source = new ObservableCollection<Category>()
        {
            new Category { Name = "Products"},
            new Category { Name = "Purchase"},
            new Category { Name = "Support"},
            new Category { Name = "Community"}
        };

        this.LoadOnDemandCommand = new Command(async (p) => await this.LoadOnDemandExecute(p), (p) => this.IsLoadOnDemandEnabled(p));
    }
    private bool IsLoadOnDemandEnabled(object p)
    {
        var context = (TreeViewLoadOnDemandCommandContext)p;
        return context.Item is Category;
    }
    async private Task LoadOnDemandExecute(object p)
    {
        var context = (TreeViewLoadOnDemandCommandContext)p;
        var category = context.Item as Category;
        if (category != null)
        {
            ObservableCollection<string> children = await Task.Run(() => this.LoadChildren(category));
            category.Children = children;
            context.Finish();
        }
    }
    private ObservableCollection<string> LoadChildren(Category category)
    {
        Task.Delay(1000).Wait();

        Dictionary<string, ObservableCollection<string>> allItems = new Dictionary<string, ObservableCollection<string>>();
        allItems.Add("Products", new ObservableCollection<string>() { "Telerik UI for Xamarin", "Telerik UI for WPF", "Telerik Reporting" });
        allItems.Add("Purchase", new ObservableCollection<string>() { "Buy now", "License Agreement", "Policies" });
        allItems.Add("Support", new ObservableCollection<string>() { "Support Center", "Knowledge Base", "Demos", "Tutorials" });
        allItems.Add("Community", new ObservableCollection<string>() { "Learning Resources", "Blogs", "Forums" });

        var result = new ObservableCollection<string>();
        bool hasChildren = allItems.TryGetValue(category.Name, out result);

        return result;
    }

IsLoadOnDemandEnabled method is called when each item is initialized and defines whether a load-on-demand feature is enabled for this item.

Finally, define RadTreeView with the needed TreeViewDescriptors as well as the LoadOnDemandCommand applied:

<telerikDataControls:RadTreeView x:Name="treeView" ItemsSource="{Binding Source}" >
    <telerikDataControls:RadTreeView.Commands>
        <treeView:TreeViewUserCommand Id="LoadOnDemand" Command="{Binding LoadOnDemandCommand}" />
    </telerikDataControls:RadTreeView.Commands>
    <telerikDataControls:TreeViewDescriptor DisplayMemberPath="Name"
                                            ItemsSourcePath="Children"
                                            TargetType="{x:Type local:Category}"/>
    <telerikDataControls:TreeViewDescriptor TargetType="{x:Type x:String}" />
</telerikDataControls:RadTreeView>

All that is left, is to set the BindingContext to the ViewModel:

this.BindingContext = new ViewModel();

Here is how the TreeView looks when load-on-demand is requested:

TreeView LoadOnDemand

The sample here demonstrates only one-level hieararchy, however, in a real scenario you could use multi-level hieararchy with lazy loading without a problem.

You can check a runnable demo in the Features section of the RadTreeView component in the SDK Samples Browser application(can be found in the Examples folder of your local Telerik UI for Xamarin installation)

See Also

Is this article helpful? Yes / No
Thank you for your feedback!

Give article feedback

Tell us how we can improve this article

close
Dummy