CollectionView isn't rendering any items after updating ObservableProperty on Windows. (Maui)

48 Views Asked by At

I am trying to use a CollectionView that gets bound to some data loaded from an external API. I am using the MVVM toolkit to create Observable properties in my ViewModel.

  <CollectionView x:Name="collectionView"  
                      ItemsSource="{Binding MyCollection}" 
                      SelectionMode="None" 
                      HorizontalOptions="FillAndExpand">
          <CollectionView.ItemsLayout>
              <LinearItemsLayout Orientation="Vertical" ItemSpacing="8" />
          </CollectionView.ItemsLayout>
          <CollectionView.ItemTemplate>
              <DataTemplate x:DataType="models:MyModel">
                  <Border>
                      <VerticalStackLayout>
                        ...snip
                      </VerticalStackLayout>
                  </Border>
              </DataTemplate>
          </CollectionView.ItemTemplate>
       <CollectionView.EmptyView>
          <Label Text="Placeholder for empty collection" />
       </CollectionView.EmptyView>
   </CollectionView>

My ViewModel looks something like this.

 public partial class MyViewModel : ObservableObject
 {
     private readonly IApiClient apiClient;

     [ObservableProperty]
     private IEnumerable<MyModel>? myCollection;

     public TripListViewModel(IApiClient apiClient)
     {
         this.apiClient= apiClient;
     }

     [RelayCommand]
     public async Task RefreshDataAsync(CancellationToken cancellationToken = default)
     {
        //delay is for debugging purposes
         await Task.Delay(3000);

         IEnumerable<MyModel> data = await apiClient.GetDataAsync();
         this.MyCollection = data;
     }

 }

Code Behind:

public partial class MyPage : ContentPage
{
    private readonly MyViewModel viewModel;

    public MyPage (MyViewModel viewModel)
    {
        this.viewModel = viewModel;
        this.BindingContext = viewModel;
        InitializeComponent();
    }

    protected override void OnNavigatedTo(NavigatedToEventArgs args)
    {
        base.OnNavigatedTo(args);
        Task.Run(async () =>
        {
            await viewModel.RefreshDataAsync();
        });
    }
}

When I run this, I can see the Empty Collection message for 3 seconds ("Placeholder for empty collection"), but then the Content of the CollectionView disappears entirely.

If I set a background color on the CollectionView, I can see that it is taking up space, but no items are rendering inside of it.

Things I have tried that didn't work.

  • Assigning MyCollection from the UI thread.
  • Calling RefreshDataAsync in OnAppearing and OnBindingContextChanged
  • Not wrapping the call to RefreshDataAsync with Task.Run
  • Verfied that GetDataAsync is returning items (about 30)
  • Set MinimumHeightRequest on the <Border>

I've only observed this issue on Windows. To make it more worse, it occasionally works! On roughly 3/4 runs, I see nothing in the CollectionView, but about 1/4 of the time, the ColectionView renders correctly. This tells me that it might be some sort of race condition, but I don't see it.

0

There are 0 best solutions below