Articles in this section
Category / Section

How to bind data using Reactive MVVM in Xamarin.Forms TreeView (SfTreeView)

7 mins read

The SfTreeView allows you to bind ItemTemplate to the reactive UI ViewModel which is a composable and cross-platform model-view-viewmodel framework for all .NET platforms.

To achieve this, follow the below steps:

STEP 1: Install the ReactiveUI and ReactiveUI.XamForms in your project.

STEP 2: Create ViewModel which should implement ReactiveObject.

public class ViewModel : ReactiveObject
{
    #region Fields
 
    private ObservableCollection<FileManager> imageNodeInfo;
 
    #endregion
 
    #region Constructor
 
    public ViewModel()
    {
        GenerateSource();
    }
 
    #endregion
 
    #region Properties
 
    public ObservableCollection<FileManager> ImageNodeInfo
    {
        get { return imageNodeInfo; }
        set { this.RaiseAndSetIfChanged(ref imageNodeInfo, value); }
    }
 
    #endregion
    #region Generate Source
    private void GenerateSource()
    {
        var nodeImageInfo = new ObservableCollection<FileManager>();
        Assembly assembly = typeof(MainPage).GetTypeInfo().Assembly;
        var doc = new FileManager() { ItemName = "Documents", ImageIcon = ImageSource.FromResource("TreeViewXamarin.Icons.treeview_folder.png", assembly) };
        var download = new FileManager() { ItemName = "Downloads", ImageIcon = ImageSource.FromResource("TreeViewXamarin.Icons.treeview_folder.png", assembly) };
        var mp3 = new FileManager() { ItemName = "Music", ImageIcon = ImageSource.FromResource("TreeViewXamarin.Icons.treeview_folder.png", assembly) };
        var pictures = new FileManager() { ItemName = "Pictures", ImageIcon = ImageSource.FromResource("TreeViewXamarin.Icons.treeview_folder.png", assembly) };
        var video = new FileManager() { ItemName = "Videos", ImageIcon = ImageSource.FromResource("TreeViewXamarin.Icons.treeview_folder.png", assembly) };
 
        var pollution = new FileManager() { ItemName = "Environmental Pollution.docx", ImageIcon = ImageSource.FromResource("TreeViewXamarin.Icons.treeview_word.png", assembly) };
        var globalWarming = new FileManager() { ItemName = "Global Warming.ppt", ImageIcon = ImageSource.FromResource("TreeViewXamarin.Icons.treeview_ppt.png", assembly) };
        var sanitation = new FileManager() { ItemName = "Sanitation.docx", ImageIcon = ImageSource.FromResource("TreeViewXamarin.Icons.treeview_word.png", assembly) };
        var socialNetwork = new FileManager() { ItemName = "Social Network.pdf", ImageIcon = ImageSource.FromResource("TreeViewXamarin.Icons.treeview_pdf.png", assembly) };
        var youthEmpower = new FileManager() { ItemName = "Youth Empowerment.pdf", ImageIcon = ImageSource.FromResource("TreeViewXamarin.Icons.treeview_pdf.png", assembly) };
 
        var games = new FileManager() { ItemName = "Game.exe", ImageIcon = ImageSource.FromResource("TreeViewXamarin.Icons.treeview_exe.png", assembly) };
        var tutorials = new FileManager() { ItemName = "Tutorials.zip", ImageIcon = ImageSource.FromResource("TreeViewXamarin.Icons.treeview_zip.png", assembly) };
        var typeScript = new FileManager() { ItemName = "TypeScript.7z", ImageIcon = ImageSource.FromResource("TreeViewXamarin.Icons.treeview_zip.png", assembly) };
        var uiGuide = new FileManager() { ItemName = "UI-Guide.pdf", ImageIcon = ImageSource.FromResource("TreeViewXamarin.Icons.treeview_pdf.png", assembly) };
 
        var song = new FileManager() { ItemName = "Gouttes", ImageIcon = ImageSource.FromResource("TreeViewXamarin.Icons.treeview_mp3.png", assembly) };
 
        var camera = new FileManager() { ItemName = "Camera Roll", ImageIcon = ImageSource.FromResource("TreeViewXamarin.Icons.treeview_folder.png", assembly) };
        var stone = new FileManager() { ItemName = "Stone.jpg", ImageIcon = ImageSource.FromResource("TreeViewXamarin.Icons.treeview_png.png", assembly) };
        var wind = new FileManager() { ItemName = "Wind.jpg", ImageIcon = ImageSource.FromResource("TreeViewXamarin.Icons.treeview_png.png", assembly) };
 
        var img0 = new FileManager() { ItemName = "WIN_20160726_094117.JPG", ImageIcon = ImageSource.FromResource("TreeViewXamarin.Icons.treeview_img0.png", assembly) };
        var img1 = new FileManager() { ItemName = "WIN_20160726_094118.JPG", ImageIcon = ImageSource.FromResource("TreeViewXamarin.Icons.treeview_img1.png", assembly) };
 
        var video1 = new FileManager() { ItemName = "Naturals.mp4", ImageIcon = ImageSource.FromResource("TreeViewXamarin.Icons.treeview_video.png", assembly) };
        var video2 = new FileManager() { ItemName = "Wild.mpeg", ImageIcon = ImageSource.FromResource("TreeViewXamarin.Icons.treeview_video.png", assembly) };
 
        doc.SubFiles = new ObservableCollection<FileManager>
        {
            pollution,
            globalWarming,
            sanitation,
            socialNetwork,
            youthEmpower
        };
 
        download.SubFiles = new ObservableCollection<FileManager>
        {
            games,
            tutorials,
            typeScript,
            uiGuide
        };
 
        mp3.SubFiles = new ObservableCollection<FileManager>
        {
            song
        };
 
        pictures.SubFiles = new ObservableCollection<FileManager>
        {
            camera,
            stone,
            wind
        };
        camera.SubFiles = new ObservableCollection<FileManager>
        {
            img0,
            img1
        };
 
        video.SubFiles = new ObservableCollection<FileManager>
        {
            video1,
            video2
        };
 
        nodeImageInfo.Add(doc);
        nodeImageInfo.Add(download);
        nodeImageInfo.Add(mp3);
        nodeImageInfo.Add(pictures);
        nodeImageInfo.Add(video);
        imageNodeInfo = nodeImageInfo;
    }
    #endregion
}

STEP 3: ContentPage should inherit from ReactiveContentPage<TViewModel> and we are going to use ReactiveUI Binding to bind our ViewModel to our View.

 

XMAL

public partial class MainPage : ReactiveContentPage<ViewModel>
{
        public MainPage(ViewModel viewModel)
        {
            
        }
}

 

C#

<rxui:ReactiveContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:rxui="clr-namespace:ReactiveUI.XamForms;assembly=ReactiveUI.XamForms"
             xmlns:local="clr-namespace:TreeViewXamarin"
             xmlns:syncfusion="clr-namespace:Syncfusion.XForms.TreeView;assembly=Syncfusion.SfTreeView.XForms"
             x:Class="TreeViewXamarin.MainPage"
             x:TypeArguments="local:ViewModel">
    <ContentPage.Content>
        <syncfusion:SfTreeView x:Name="treeView"
                           ItemHeight="40"
                           Indentation="15"
                           ExpanderWidth="40"
                           ChildPropertyName="SubFiles"
                           ItemTemplateContextType="Node"
                           ItemsSource="{Binding ImageNodeInfo}"
                            >
            <syncfusion:SfTreeView.ItemTemplate>
                <DataTemplate>
                    <Grid x:Name="grid" RowSpacing="0" >
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*" />
                            <RowDefinition Height="1" />
                        </Grid.RowDefinitions>
                        <Grid RowSpacing="0" Grid.Row="0">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="40" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <Grid Padding="5,5,5,5">
                                <Image Source="{Binding Content.ImageIcon}"
                                   VerticalOptions="Center"
                                   HorizontalOptions="Center"
                                   HeightRequest="35" 
                                   WidthRequest="35"/>
                            </Grid>
                            <Grid Grid.Column="1"              
                              RowSpacing="1"
                              Padding="1,0,0,0"
                              VerticalOptions="Center">
                                <Label LineBreakMode="NoWrap"
                                   Text="{Binding Content.ItemName}"
                                   VerticalTextAlignment="Center">
                                </Label>
                            </Grid>
                        </Grid>
                        <StackLayout Grid.Row="1"/>
                    </Grid>
                </DataTemplate>
            </syncfusion:SfTreeView.ItemTemplate>
        </syncfusion:SfTreeView>
    </ContentPage.Content>
</rxui:ReactiveContentPage>

STEP 4: View can be connected in one-way dependent manner to the ViewModel through bindings. You can set the BindingContext for the SfTreeView in MainPage.cs itself in code behind like below.

 

public partial class MainPage : ReactiveContentPage<ViewModel>
{
        public MainPage(ViewModel viewModel)
        {
            ViewModel = viewModel;
            InitializeComponent();
        }
}

View Sample in GitHub

Gif

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