[Android] CollectionView: VirtualView cannot be null here, when clearing and adding items on second navigation

See original GitHub issue

Description

An Exception occurs when adding item to ObservableCollection with an EmptyView after having navigated to the same page for a second time.

System.InvalidOperationException: ‘VirtualView cannot be null here’

The exception occurs:

  • Only on Android (works fine on Windows)
  • Only when navigating to the page a second (or third…) time
  • I tried using VS 17.4.3, as well as 17.5.0 Preview 2.0, both latest as of today maui-android 7.0.52/7.0.100 VS 17.4.33205.214, VS 17.5.33209.295
  • Using both CollectionView EmptyView="something" as well as using separate <CollectionView.EmptyView><ContentView>...

Steps to Reproduce

  1. Create a File > New .NET MAUI App
  2. Add a second ContentPage to the project, named “Page2”
  3. In AppShell.xaml.cs add: Routing.RegisterRoute("Page2", typeof(Page2));
  4. In MauiProgram.cs add: builder.Services.AddScoped<Page2>();
  5. In Page2.xaml remove the Label and replace with:
<CollectionView ItemsSource="{Binding Values}">
            
    <CollectionView.EmptyView>
        <ContentView>
            <Label Text="No items"
                    FontAttributes="Bold" />
        </ContentView>
    </CollectionView.EmptyView>
            
    <CollectionView.ItemTemplate>
        <DataTemplate x:DataType="x:String">
            <Label Text="{Binding .}" />
        </DataTemplate>
    </CollectionView.ItemTemplate>
            
</CollectionView>

<Button
    Text="Load items"
    Pressed="Button_Pressed" />
  1. In Page2.xaml.cs replace the class with:
public partial class Page2 : ContentPage
{
	public ObservableCollection<string> Values { get; set; } = new();

	public Page2()
	{
		InitializeComponent();

		this.BindingContext = this;
	}

	private async void Button_Pressed(object sender, EventArgs e)
	{
		Values.Clear();

		await Task.Delay(1000);

		for (int i = 1; i <= 5; i++)
			Values.Add($"Item #{i}");
	}
}
  1. In MainPage.xaml.cs modify OnCounterClicked as follows:
private async void OnCounterClicked(object sender, EventArgs e)
{
	count++;

	if (count == 1)
		CounterBtn.Text = $"Clicked {count} time";
	else
		CounterBtn.Text = $"Clicked {count} times";

	SemanticScreenReader.Announce(CounterBtn.Text);

    await Shell.Current.GoToAsync("/Page2");
}
  1. Run the app on Android
  2. Click the button on MainPage
  3. Click the button on Page2 two or more times --> works fine
  4. Go back to MainPage
  5. Click the button on MainPage again
  6. Click the button on Page2 --> Exception occurrs:
System.InvalidOperationException: VirtualView cannot be null here    at Microsoft.Maui.Handlers.ViewHandler`2[[Microsoft.Maui.Controls.ReorderableItemsView, Microsoft.Maui.Controls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[AndroidX.RecyclerView.Widget.RecyclerView, Xamarin.AndroidX.RecyclerView, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].get_VirtualView() in D:\a\_work\1\s\src\Core\src\Handlers\View\ViewHandlerOfT.cs:line 42    at Microsoft.Maui.Controls.Handlers.Items.StructuredItemsViewHandler`1[[Microsoft.Maui.Controls.ReorderableItemsView, Microsoft.Maui.Controls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].GetItemsLayout() in D:\a\_work\1\s\src\Controls\src\Core\Handlers\Items\StructuredItemsViewHandler.Android.cs:line 10    at Microsoft.Maui.Controls.Handlers.Items.MauiRecyclerView`3[[Microsoft.Maui.Controls.ReorderableItemsView, Microsoft.Maui.Controls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Microsoft.Maui.Controls.Handlers.Items.GroupableItemsViewAdapter`2[[Microsoft.Maui.Controls.ReorderableItemsView, Microsoft.Maui.Controls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Microsoft.Maui.Controls.Handlers.Items.IGroupableItemsViewSource, Microsoft.Maui.Controls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], Microsoft.Maui.Controls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Microsoft.Maui.Controls.Handlers.Items.IGroupableItemsViewSource, Microsoft.Maui.Controls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].UpdateLayoutManager() in D:\a\_work\1\s\src\Controls\src\Core\Handlers\Items\Android\MauiRecyclerView.cs:line 288    at Microsoft.Maui.Controls.Handlers.Items.MauiRecyclerView`3[[Microsoft.Maui.Controls.ReorderableItemsView, Microsoft.Maui.Controls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Microsoft.Maui.Controls.Handlers.Items.GroupableItemsViewAdapter`2[[Microsoft.Maui.Controls.ReorderableItemsView, Microsoft.Maui.Controls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Microsoft.Maui.Controls.Handlers.Items.IGroupableItemsViewSource, Microsoft.Maui.Controls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], Microsoft.Maui.Controls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Microsoft.Maui.Controls.Handlers.Items.IGroupableItemsViewSource, Microsoft.Maui.Controls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].UpdateEmptyViewVisibility() in D:\a\_work\1\s\src\Controls\src\Core\Handlers\Items\Android\MauiRecyclerView.cs:line 552    at Microsoft.Maui.Controls.Handlers.Items.DataChangeObserver.OnItemRangeInserted(Int32 positionStart, Int32 itemCount) in D:\a\_work\1\s\src\Controls\src\Core\Handlers\Items\Android\DataChangeObserver.cs:line 53    at AndroidX.RecyclerView.Widget.RecyclerView.AdapterDataObserver.n_OnItemRangeInserted_II(IntPtr jnienv, IntPtr native__this, Int32 positionStart, Int32 itemCount) in C:\a\_work\3\s\generated\androidx.recyclerview.recyclerview\obj\Release\net6.0-android\generated\src\AndroidX.RecyclerView.Widget.RecyclerView.cs:line 1124    at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PPII_V(_JniMarshal_PPII_V callback, IntPtr jnienv, IntPtr klazz, Int32 p0, Int32 p1) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:line 154

Link to public reproduction project repository

https://github.com/jaldinger/MauiAppRepro1.App

Version with bug

7.0

Last version that worked well

Unknown/Other

Affected platforms

Android

Affected platform versions

Android (tested 8.1)

Did you find any workaround?

Removing the EmptyView from the CollectionView avoids the exception (but removes the EmtpyView).

Relevant log output

No response

Issue Analytics

  • State:closed
  • Created 9 months ago
  • Reactions:9
  • Comments:12 (1 by maintainers)

github_iconTop GitHub Comments

5reactions
lucianparvucommented, Jan 17, 2023

Same Problem here too

1reaction
jerry08commented, Jan 28, 2023

@7702244 Pull requests were already submitted for some but were closed since the team is focusing on other matters. That’s why I posted some workarounds in the meanwhile.

Read more comments on GitHub >

github_iconTop Results From Across the Web

What is up with capturing Xamarin CollectionView ...
There is a workaround for this issue, try using VisualStateManager to add the selected effect. <DataTemplate> <Frame> <VisualStateManager.
Read more >
View | Android Developers
When a user is navigating a user interface via directional keys such as a D-pad, it is necessary to give focus to actionable...
Read more >
MAUI Navigation is Returning Null
Here's the code snippet for your reference on navigating from the first page to second page: Create a view service: ViewServices.cs. public ...
Read more >
How do I avoid the Content covering revealed SwipeItems ...
I am trying to implement SwipeView based UI (MAUI Android) for CollectionView list items Edit and Delete actions. The issue I am having...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found