I'm trying to display a scrollable list in a popup with a CollectionView and I get an exception "Collection was modified; enumeration operation may not execute" as soon as it is displayed. I don't understand why because my binded list with ItemsSource is never modified.
Thanks for your help.
This is PopupTest.xaml
<?xml version="1.0" encoding="utf-8" ?>
<toolkit:Popup xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
x:Class="Popup.PopupTest">
<Grid>
<CollectionView ItemsSource="{Binding Sources}"
ItemSizingStrategy="MeasureAllItems"
VerticalScrollBarVisibility="Always"
SelectionMode="Single">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical"
ItemSpacing="0" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Margin="10,10,10,10"
RowSpacing="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0"
Source="{Binding ...}"
WidthRequest="40"
HeightRequest="40"
Margin="15,10,25,10" />
<Label Grid.Column="1"
Text="{Binding ...}"
Margin="0,0,25,0"
FontSize="17"
LineBreakMode="WordWrap"
MaxLines="2"
HorizontalOptions="Start"
VerticalOptions="Center" />
<RadioButton Grid.Column="2"
IsChecked="{Binding ...}" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
</toolkit:Popup>
This is PopupTest.xaml.cs
public partial class PopupTest : CommunityToolkit.Maui.Views.Popup
{
public ObservableCollection<...> Sources { get; set; }
public PopupTest()
{
Sources = new ObservableCollection<...>([other list]);
InitializeComponent();
}
}
This is how I display the popup
var popup = new PopupTest();
this.ShowPopup(popup);
Here I made a demo using CommunityToolkit Popup. I am using .NET8.0
with CommunityToolkit.Maui 7.0.1
targeting on Android emulator.
After I create a default maui project. I add a Popup Page to my project mostly based on your code. Here it is,
1.the XAML for Popup,
<toolkit:Popup xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp2.PopupTest"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
>
<Grid WidthRequest="400" HeightRequest="600">
<CollectionView ItemsSource="{Binding Sources}"
ItemSizingStrategy="MeasureAllItems"
VerticalScrollBarVisibility="Always"
SelectionMode="Single">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical"
ItemSpacing="0" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Margin="10,10,10,10"
RowSpacing="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0"
Source="{Binding ImageName}"
WidthRequest="40"
HeightRequest="40"
Margin="15,10,25,10" />
<Label Grid.Column="1"
Text="{Binding Name}"
Margin="0,0,25,0"
FontSize="17"
LineBreakMode="WordWrap"
MaxLines="2"
HorizontalOptions="Start"
VerticalOptions="Center" />
<RadioButton Grid.Column="2"
IsChecked="{Binding IsChecked}" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
</toolkit:Popup>
2.the code behind for Popup.
public partial class PopupTest : Popup
{
public PopupTest()
{
InitializeComponent();
BindingContext = new MyPopupViewModel();
}
}
3.the ViewModel for Popup. I just add some test data in it,
public class MyPopupViewModel
{
public ObservableCollection<Item> Sources { get; set; }
public IList<Item> items { get; set; } = new List<Item>();
public MyPopupViewModel()
{
items.Add(new Item { ImageName = "dotnet_bot.png", IsChecked = true, Name = "Item1" });
items.Add(new Item { ImageName = "dotnet_bot.png", IsChecked = false, Name = "Item2" });
items.Add(new Item { ImageName = "dotnet_bot.png", IsChecked = false, Name = "Item3" });
items.Add(new Item { ImageName = "dotnet_bot.png", IsChecked = false, Name = "Item5" });
items.Add(new Item { ImageName = "dotnet_bot.png", IsChecked = true, Name = "Item4" });
Sources = new ObservableCollection<Item>(items);
}
}
public class Item
{
public string Name { get; set; }
public string ImageName { get; set; }
public bool IsChecked { get; set; }
}
And after I click the button on MainPage,
private void OnCounterClicked(object sender, EventArgs e)
{
var popup = new PopupTest();
this.ShowPopup(popup);
}
Here is the effect on Android 13.0 - Pixel5 emulator,