Articles in this section
Category / Section

How to fetch data using Web API in Xamarin.Forms TreeView

5 mins read

You can populate data from WebAPI and populate the fetched data in the Xamarin.Forms SfTreeView.

STEP 1: Install the ModernHttpClient and Newtonsoft.Json NuGet packages in the shared code project. 

STEP 2: Retrieve data from the Web service

Define the HTTPClient to retrieve information from the web server for a specified url using the GetAsync method. Use the HTTPContent.ReadAsStringAsync method to read the retrieved data into string format. Using, JsonConvert.DeserializeObject method, convert the JSON string to ObservableCollection.

internal class WebApiServices
{
    public static string webApiUrl = "https://ej2services.syncfusion.com/production/web-services/api/Orders"; // Your Web Api here
 
    System.Net.Http.HttpClient client;
 
    public WebApiServices()
    {
        client = new System.Net.Http.HttpClient();
    }
 
    /// <summary>
    /// Retrieves data from the web service.
    /// </summary>
    /// <returns>Returns the ObservableCollection.</returns>
    public async System.Threading.Tasks.Task<ObservableCollection<RootTree>> RefreshDataAsync()
    {
        var uri = new Uri(webApiUrl);
        try
        {
            //Sends request to retrieve data from the web service for the specified Uri
            var response = await client.GetAsync(uri);
 
            if (response.IsSuccessStatusCode)
            {
                var content = await response.Content.ReadAsStringAsync(); //Returns the response as JSON string
                return JsonConvert.DeserializeObject<ObservableCollection<RootTree>>(content); //Converts JSON string to ObservableCollection
            }
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine(@"ERROR {0}", ex.Message);
        }
 
        return null;
    }
}

STEP 3: Create Xamarin.Forms application with SfTreeView

Define SfTreeView bound to the ViewModel collection. You can populate child items using the LoadOnDemandCommand in SfTreeView. You can refer to the LoadOnDemand document from here.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:syncfusion="clr-namespace:Syncfusion.XForms.TreeView;assembly=Syncfusion.SfTreeView.XForms"
             xmlns:SfButtons="clr-namespace:Syncfusion.XForms.Buttons;assembly=Syncfusion.Buttons.XForms"
             xmlns:local="clr-namespace:TreeViewXamarin"
             x:Class="TreeViewXamarin.MainPage">
 
    <ContentPage.BindingContext>
        <local:CountriesViewModel x:Name="viewModel"/>
    </ContentPage.BindingContext>
 
    <StackLayout>
        <syncfusion:SfTreeView x:Name="treeView" 
                               ItemTemplateContextType="Node" 
                               ItemsSource="{Binding CountriesInfo}"
                               CheckBoxMode="Recursive"
                               CheckedItems="{Binding CheckedItems}"
                               LoadOnDemandCommand="{Binding TreeViewOnDemandCommand}">
            <syncfusion:SfTreeView.ItemTemplate>
                <DataTemplate>
                    <Grid Padding="5">
                        <SfButtons:SfCheckBox x:Name="CheckBox"
                                              Text="{Binding Content.Name}"
                                              IsChecked="{Binding IsChecked, Mode=TwoWay}"
                                              VerticalOptions="CenterAndExpand"/>
                    </Grid>
                </DataTemplate>
            </syncfusion:SfTreeView.ItemTemplate>
        </syncfusion:SfTreeView>
    </StackLayout>
</ContentPage>

STEP 4: Populate data to collection

In the ViewModel class, initialize the WebService and populate the data by invoking the GetDataAsync method in the LoadOnDemand execute method.

public class EmployeeManagerViewModel : INotifyPropertyChanged
{
    WebApiServices webApiServices;
    public ICommand TreeViewOnDemandCommand { get; set; }
 
    public EmployeeManagerViewModel()
    {
        webApiServices = new WebApiServices();
        TreeViewOnDemandCommand = new Command(ExecuteOnDemandLoading, CanExecuteOnDemandLoading);
 
        GetParentNodes();
    }
 
    /// <summary>
    /// CanExecute method is called before expanding and initialization of node. Returns whether the node has child nodes or not.
    /// Based on return value, expander visibility of the node is handled.  
    /// </summary>
    /// <param name="sender">TreeViewNode is passed as default parameter </param>
    /// <returns>Returns true, if the specified node has child items to load on demand and expander icon is displayed for that node, else returns false and icon is not displayed.</returns>
    private bool CanExecuteOnDemandLoading(object sender)
    {
        return ((sender as TreeViewNode).Content as Employee).HasChildNodes;
    }
 
    /// <summary>
    /// Execute method is called when any item is requested for load-on-demand items.
    /// </summary>
    /// <param name="obj">TreeViewNode is passed as default parameter </param>
    private void ExecuteOnDemandLoading(object obj)
    {
        var node = obj as TreeViewNode;
 
        // Skip the repeated population of child items when every time the node expands.
        if (node.ChildNodes.Count > 0)
        {
            node.IsExpanded = true;
            return;
        }
 
        //Animation starts for expander to show progressing of load on demand
        node.ShowExpanderAnimation = true;
        Device.BeginInvokeOnMainThread(async () =>
        {
            //Fetching child items to add
            var items = await GetDataAsync();
 
            
            await Task.Delay(500);
           
            // Populating child items for the node in on-demand
            node.PopulateChildNodes(items);
            if (items.Count() > 0)
                //Expand the node after child items are added.
                node.IsExpanded = true;
 
            //Stop the animation after load on demand is executed, if animation not stopped, it remains still after execution of load on demand.
            node.ShowExpanderAnimation = false;
        });
    }
 
    /// <summary>
    /// Gets data from the web service and return the collection of fetched data.
    /// </summary>
    private async Task<ObservableCollection<Countries>> GetDataAsync()
    {
        var rootItems = await webApiServices.RefreshDataAsync();
        return this.ProcessChildData(rootItems);
    }
 
    /// <summary>
    /// Processe the fetched data with child items. 
    /// </summary>
    /// <param name="rootData">Data fetched from the web service.</param>
    /// <returns>Returns the processed data for child nodes.</returns>
    private ObservableCollection<Countries> ProcessChildData(ObservableCollection<RootTree> rootData)
    {
        var details = new ObservableCollection<Countries>();
        var random = new Random();
        var employees = rootData.Where(x => x.EmployeeID == random.Next(1, 10)).GroupBy(x => x.ShipCity).Select(y => y.First()).ToList<RootTree>();
           
        foreach (var item in employees)
        {
            var child = new Countries() { Name = item.ShipCity };
 
            //Added CheckedItems to check multiple items through binding.
            if (item.Verified == "true")
            {
                CheckedItems.Add(child);
            }
            details.Add(child);
        }
 
        return details;
    }
}

View sample in GitHub

How to consume Web Api in Xamarin.Forms SfTreeView

Did you find this information helpful?
Yes
No
Help us improve this page
Please provide feedback or comments
Comments (0)
Please sign in to leave a comment
Access denied
Access denied