Darvin Segura
Darvin Segura

Reputation: 3

Xamarin Listview don't show the observable Collection

I'm using Xamarin.Forms MVVM to develop my app, and don't found what I'm doing wrong, I have an ObservableCollection with the values from web API, and when I set a break point all the values are good even in the view when I see the values of the binding source everything have the value, but the values are not showing up in my ListView.

Here is the ViewModel

class DatosMedicosViewModel : BaseViewModel
{
    private ApiService apiService;

    private ObservableCollection<Land> land;
    private bool isRefreshing;

    public ObservableCollection<Land> Lands
    {
        get { return this.land; }
        set { SetValue(ref this.land, value); }
    }

    public bool IsRefreshing
    {
        get { return this.isRefreshing; }
        set { SetValue(ref this.isRefreshing, value); }
    }

    public DatosMedicosViewModel()
    {
        this.apiService = new ApiService();
        this.LoadLand();
    }

    private async void LoadLand()
    {
        this.IsRefreshing = true;
        var connection = await this.apiService.CheckConnection();
        if (!connection.IsSuccess)
        {
            this.IsRefreshing = false;
            await Application.Current.MainPage.DisplayAlert(
                "Error",
                connection.Message,
                "Accept");
            await Application.Current.MainPage.Navigation.PopAsync();
            return;
        }

        var response = await this.apiService.GetList<Land>(
           "url Base",
           "prefix",
           "Controller");

        if (!response.IsSuccess)
        {
            this.IsRefreshing = false;
            await Application.Current.MainPage.DisplayAlert(
                "Error",
                response.Message,
                "Accept"
                );
            return;
        }

        var list = (List<Land>)response.Result;
        this.Lands = new ObservableCollection<Land>(list);
        this.IsRefreshing = false;
    }

    public ICommand RefreshCommand
    {
        get
        {
            return new RelayCommand(LoadLand);
        }
    }
}

Here is the View

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ARLAPP.Views.ConsultaPage"
             BackgroundColor="White"
             BindingContext="{Binding Main, Source={StaticResource Locator}}"
             Title="Lands">
    <ContentPage.Content>
        <StackLayout 
            BindingContext="{Binding Lands}"
            Padding="5">
            <StackLayout>
                <Image 
                VerticalOptions="Center"
                WidthRequest="300"
                Source="UserIcon"
                BackgroundColor="Transparent"/>
                <Label Text="Mark"
                       VerticalOptions="Center"
                       HorizontalOptions="CenterAndExpand"
                       FontAttributes="Bold"
                       FontSize="Medium"/>
            </StackLayout>
            <StackLayout>
                <ListView
                SeparatorVisibility="Default"
                FlowDirection="LeftToRight"
                BackgroundColor="White"
                ItemsSource="{Binding Lands}"
                HasUnevenRows="True">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <ViewCell>
                                <Label   
                                    Grid.Column="2"
                                    VerticalOptions="Center"
                                    TextColor="Black"
                                    Text="{Binding Currency}"/>

                            </ViewCell>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </StackLayout>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

Here how I call the view

if (this.PageName == "Lands")
{
    MainViewModel.GetInstance().Lands= new LandViewModel();
    Application.Current.MainPage = new LandMasterPage();
}

Upvotes: 0

Views: 83

Answers (1)

Joehl
Joehl

Reputation: 3701

Check your BindingContext. I think you are setting it wrong in your view.

In your top-level StackLayout you set the the BindingContext to your property: BindingContext="{Binding Lands}". And in your ListView you set the ItemsSource also to this property: ItemsSource="{Binding Lands}". That won't work because the ListView is trying to bind to a property Lands inside your BindingContext, which is also set to Lands.

Remove the BindingContext from your top-level StackLayout, because you don't need it.

Ensure the BindingContext of your page ConsultaPage is set to your view-model DatosMedicosViewModel.

Sample of setting the bindingcontext (abstract code):

var mypage = new ConsultaPage();
mypage.BindingContext = new DatosMedicosViewModel();

await Navigation.PushAsync(mypage);

// Load your data in OnAppearing() of the page-event

This should solve your binding-problem.

Side-Note: As Abdul Gani said in the comments: Ensure you implement the INotifyPropertyChanged interface, but I assume you do this already in your BaseViewModel and call the NotifyChanged-Event in your SetValue-Method.

Upvotes: 1

Related Questions