Home > Mobile >  Xamarin Forms CollectionView is empty
Xamarin Forms CollectionView is empty

Time:02-17

I have a Xamarin Forms CollectionView, contained within a RefreshView. The binding source is populated but its not showing anything in the CollectionView. I know the binding source is populated as I show a count in the toolbar. Can anyone spot why the list is empty?

Here is my Content Page with my RefreshView and CollectionView:

<ContentPage.ToolbarItems>
    <ToolbarItem Text="Add" Command="{Binding AddDogCommand}" />
    <ToolbarItem Text="{Binding Dogs.Count}"></ToolbarItem>
</ContentPage.ToolbarItems>
<RefreshView x:DataType="local:MyDogsViewModel" Command="{Binding LoadDogsCommand}" IsRefreshing="{Binding IsBusy, Mode=TwoWay}">
    <CollectionView ItemsLayout="HorizontalList" ItemsSource="{Binding Dogs}">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <Grid WidthRequest="100">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>                       
                    <Label Grid.Column="1"
                   Text="{Binding DogName}"
                   FontAttributes="Bold" TextColor="Red"/>
                    <Label Grid.Row="1"
                   Grid.Column="1"
                   Text="{Binding Nickname}"
                   FontAttributes="Italic" TextColor="Green"
                   VerticalOptions="End" />
                </Grid>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</RefreshView>

Here is my ViewModel

public class MyDogsViewModel : BaseViewModel
{
    private DogModel _selectedItem;

    private DogService dogService = new DogService();

    private string _dogName;

    private string _nickname;
    
    public ObservableCollection<DogModel> Dogs { get; }
    
    public Command LoadDogsCommand { get; }
    
    public Command<DogModel> ItemTapped { get; }

    public Command AddDogCommand { get; }

    public Command SaveDogCommand { get; }

    public string DogName
    {
        get => _dogName;
        set => SetProperty(ref _dogName, value);            
    }

    public string Nickname
    {
        get => _nickname;
        set => SetProperty(ref _nickname, value);
    }

    public MyDogsViewModel()
    {
        Title = "My Dogs";
        Dogs = new ObservableCollection<DogModel>();

        LoadDogsCommand = new Command(async () => await ExecuteLoadDogsCommand());

        ItemTapped = new Command<DogModel>(OnItemSelected);

        AddDogCommand = new Command(OnAddDog);

        SaveDogCommand = new Command(OnSaveDog);
    }

    async Task ExecuteLoadDogsCommand()
    {
        IsBusy = true;

        try
        {
            Dogs.Clear();
            var dogs = await dogService.GetDogsAsync();
            foreach (var d in dogs)
            {
                Dogs.Add(d);
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine("Exception: "   ex);
        }
        finally
        {
            IsBusy = false;
        }
    }

    public void OnAppearing()
    {
        IsBusy = true;
    }

    private async void OnAddDog(object obj)
    {
        await Shell.Current.GoToAsync(nameof(AddDogPage));
    }

    private async void OnSaveDog(object obj)
    {
        AddDogModel model = new AddDogModel
        {
            DogName = DogName,
            Nickname = Nickname
        };

        await dogService.AddDog(model);

        await Shell.Current.GoToAsync("..");
    }

    async void OnItemSelected(DogModel dog)
    {
        if (dog == null)
            return;
    }
}

DogModel class

public class DogModel
{
    public int Id { get; set; }

    public string DogName { get; set; }

    public string Nickname { get; set; }
}

CodePudding user response:

keep your xaml the same and i will edit your ViewModel and take out the properties that is causing you the issue ;

public class MyDogsViewModel : BaseViewModel
{
    private DogModel _selectedItem;

    private DogService dogService = new DogService();

    private string _dogName;

    private string _nickname;
    
    private ObservableCollection<DogModel> dogs;
    public ObservableCollection<DogModel> Dogs 
    { 
      get{return dogs;}
      set{dogs=value;}
    }
    
    public Command LoadDogsCommand { get; set; }
    
    public Command<DogModel> ItemTapped { get; set;}

    public Command AddDogCommand { get; set;}

    public Command SaveDogCommand { get; set;}
  

    public MyDogsViewModel()
    {
        Title = "My Dogs";
        Dogs = new ObservableCollection<DogModel>();

        LoadDogsCommand = new Command(async () => await ExecuteLoadDogsCommand());

        ItemTapped = new Command<DogModel>(OnItemSelected);

        AddDogCommand = new Command(OnAddDog);

        SaveDogCommand = new Command<object>(OnSaveDog);
    }

    async Task ExecuteLoadDogsCommand()
    {
        IsBusy = true;

        try
        {
            Dogs.Clear();
            var dogs = await dogService.GetDogsAsync();
            foreach (var d in dogs)
            {
                Dogs.Add(d);
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine("Exception: "   ex);
        }
        finally
        {
            IsBusy = false;
        }
    }

    public void OnAppearing()
    {
        IsBusy = true;
    }

    private async void OnAddDog(object obj)
    {
        await Shell.Current.GoToAsync(nameof(AddDogPage));
    }

    private async void OnSaveDog(object obj)
    {
        DogModel newdog = obj as DogModel;

        await dogService.AddDog(newdog);

        await Shell.Current.GoToAsync("..");
    }

    async void OnItemSelected(DogModel dog)
    {
        if (dog == null)
            return;
    }
}

dont forget to bind to the viewmodel. in the xaml.cs add this in the constuctor.

this.BindingContext = new MyDogsViewModel();
  • Related