We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date
close icon

SFListView not shows data with my infrastructure (MVVM, IoC, ...)

Hi, I'm trying to build some infrastructure to well design future mobile developments, and trying to use your controls with it. I've test your samples and they works very well, but when I try to put your controls with my plumbing, the main page, with the SFListView doesn't shows any data... Following you have my code (you can see the complete code in github: https://github.com/Kash0321/kash.triplog)

** MainView.xaml **

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:sl="clr-namespace:Syncfusion.ListView.XForms;assembly=Syncfusion.SfListView.XForms"
             xmlns:ktm="clr-namespace:kash.triplog.Main"
             xmlns:vc="clr-namespace:kash.triplog.Infrastructure.Converters;assembly=kash.triplog"
             x:Class="kash.triplog.Main.MainView"
             Title="Trip Log">

  <ContentPage.Resources>
    <ResourceDictionary>
      <vc:ReverseBooleanConverter x:Key="not" />
    </ResourceDictionary>
  </ContentPage.Resources>
  
  <ContentPage.ToolbarItems>
      <ToolbarItem Name="NewButton" Text="New" Command="{Binding NewCommand}" />
  </ContentPage.ToolbarItems>

  <StackLayout x:Name="RootLayout" HorizontalOptions="Center">
    <sl:SfListView x:Name="Entries" ItemsSource="{Binding LogEntries}" IsVisible="{Binding IsBusy, Converter={StaticResource not}}">
      <sl:SfListView.ItemTemplate>
        <DataTemplate>
          <Grid Padding="10">
            <Grid.RowDefinitions>
              <RowDefinition Height="0.4*" />
              <RowDefinition Height="0.6*" />
            </Grid.RowDefinitions>
            <Label Text="{Binding Title}" FontAttributes="Bold" TextColor="Teal" FontSize="21" />
            <Label Grid.Row="1" Text="{Binding Notes}" TextColor="Teal" FontSize="15"/>
          </Grid>
        </DataTemplate>
      </sl:SfListView.ItemTemplate>
    </sl:SfListView>
    <StackLayout x:Name="Loader" Padding="0,50,0,0" Orientation="Vertical" HorizontalOptions="Center" VerticalOptions="Center" IsVisible="{Binding IsBusy}">
      <ActivityIndicator IsRunning="true" />
      <Label Text="Cargando..." />
    </StackLayout>
  
</StackLayout>
</ContentPage>


**  MainView.xaml.cs  **

using kash.triplog.Detail;
using kash.triplog.Model;
using kash.triplog.Navigation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Xamarin.Forms;

namespace kash.triplog.Main
{
    public partial class MainView : ContentPage
    {
        MainViewModel ViewModel
        {
            get { return BindingContext as MainViewModel; }
        }

        protected override async void OnAppearing()
        {
            base.OnAppearing();

            // Initialize MainViewModel
            if (ViewModel != null)
            {
                await ViewModel.Init();
            }
        }

        public MainView()
        {
            InitializeComponent();

            Entries.ItemTapped += async (sender, e) => {
                var item = (TripLogEntry)e.ItemData;
                ViewModel.ViewCommand.Execute(item);
            };
        }
    }
}

** MainViewModel.cs **

using kash.triplog.Detail;
using kash.triplog.Infrastructure;
using kash.triplog.Model;
using kash.triplog.Navigation;
using kash.triplog.NewEntry;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;

namespace kash.triplog.Main
{
    public class MainViewModel : ViewModelBase
    {
        ObservableCollection<TripLogEntry> logEntries;
        public ObservableCollection<TripLogEntry> LogEntries
        {
            get { return logEntries; }
            set
            {
                logEntries = value;
                OnPropertyChanged();
            }
        }

        Command<TripLogEntry> viewCommand;
        public Command<TripLogEntry> ViewCommand
        {
            get
            {
                return viewCommand ?? (viewCommand = new Command<TripLogEntry>(async (entry) => await ExecuteViewCommand(entry)));
            }
        }
        Command newCommand;
        public Command NewCommand
        {
            get
            {
                return newCommand ?? (newCommand = new Command(async () => await ExecuteNewCommand()));
            }
        }

        async Task ExecuteViewCommand(TripLogEntry entry)
        {
            await NavService.NavigateTo<DetailViewModel, TripLogEntry>(entry);
        }

        async Task ExecuteNewCommand()
        {
            await NavService.NavigateTo<NewEntryViewModel>();
        }

        public MainViewModel(INavService navService) : base(navService)
        {
            LogEntries = new ObservableCollection<TripLogEntry>();
        }

        public override async Task Init()
        {
            await LoadEntries();
        }

        async Task LoadEntries()
        {
            if (IsBusy)
            {
                return;
            }

            IsBusy = true;

            LogEntries.Clear();

            await Task.Factory.StartNew(() =>
            {
                LogEntries.Add(new TripLogEntry
                {
                    Title = "Washington Monument",
                    Notes = "Amazing!",
                    Rating = 3,
                    Date = new DateTime(2015, 2, 5),
                    Latitude = 38.8895,
                    Longitude = -77.0352
                });
                LogEntries.Add(new TripLogEntry
                {
                    Title = "Statue of Liberty",
                    Notes = "Inspiring!",
                    Rating = 4,
                    Date = new DateTime(2015, 4, 13),
                    Latitude = 40.6892,
                    Longitude = -74.0444
                });
                LogEntries.Add(new TripLogEntry
                {
                    Title = "Golden Gate Bridge",
                    Notes = "Foggy, but beautiful.",
                    Rating = 5,
                    Date = new DateTime(2015, 4, 26),
                    Latitude = 37.8268,
                    Longitude = -122.4798
                });
            });

            IsBusy = false;
        }
    }
}

** App.xaml.cs **

public partial class App : Application
    {
        public IKernel Kernel { get; set; }

        public App(params INinjectModule[] platformModules)
        {
            InitializeComponent();

            var mainPage = new NavigationPage(new MainView());

            // Register core services
            Kernel = new StandardKernel(new TripLogCoreModule(), new TripLogNavModule(mainPage.Navigation));

            // Register platform specific services
            Kernel.Load(platformModules);

            // Get the MainViewModel from the IoC
            mainPage.BindingContext = Kernel.Get<MainViewModel>();

            MainPage = mainPage;
        }

        //...


1 Reply

DB Dinesh Babu Yadav Syncfusion Team January 6, 2017 08:35 AM UTC

Hi Sergio,   
   
Thanks for contacting Syncfusion Support.   
   
To achieve your requirement “SfListView doesn’t shows any data”, you must set the HorizontalOptions and VerticalOptions of the StackLayout to “LayoutOption.FillAndExpand” like below code example.   
   
Code example[XAML]:   
<StackLayout x:Name="RootLayout" HorizontalOptions="FillAndExpand"VerticalOptions="FillAndExpand">   
<sl:SfListView x:Name="Entries" ItemsSource="{Binding LogEntries}"    
               ItemSize="100" IsVisible="{Binding IsBusy, Converter={StaticResource not}}"/>   
</StackLayout>   
  
   
Additionally, when you pop out from the DetailView view by clicking back button in the given sample, the application gets crashed with the following exception “Android.Util.AndroidRuntimeException: Only the original thread that created a view hierarchy can touch its views”. This error occurs when you are doing UI operation from another thread. So, I suggest you to run the MainView in a main thread like the following example.   
   
Code example[C#]   
Device.BeginInvokeOnMainThread(() =>   
{   
    LogEntries.Add(new TripLogEntry   
    {   
       Title = "Washington Monument",   
       Notes = "Amazing!",   
       Rating = 3,   
       Date = new DateTime(2015, 2, 5),   
       Latitude = 38.8895,   
       Longitude = -77.0352   
    });   
});   
  
   
For your reference, we have modified the sample. Please find the sample link below.   
   
   
Regards,   
Dinesh Babu Yadav   
 


Loader.
Live Chat Icon For mobile
Up arrow icon