Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MAUI CollectionView SelectedItem not updating

Tags:

maui

According to the documentation (https://learn.microsoft.com/en-us/dotnet/maui/user-interface/controls/collectionview/selection) SelectedItem is two way binding but when I click on a item in the CollectionView it seems that nothing happen.

For debugging purposes I have added a button to randomly selecting an item and this is working, so I believe I have a problem in the collection binding or I need to do more wiring.

View

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Maui.Views.WorldPage"
             xmlns:viewmodels="clr-namespace:Maui.ViewModels"
             x:DataType="viewmodels:WorldViewModel"
             xmlns:models="clr-namespace:Maui.Models"
             Title="WorldPage"
             xmlns:controls="clr-namespace:Maui.Controls">
    <StackLayout>
        <controls:AreaDetailsView Area="{Binding SelectedArea}"/>
        <CollectionView ItemsSource="{Binding Areas}"
                        ItemsLayout="VerticalGrid, 7"
                        SelectionMode="Single"
                        SelectedItem="{Binding SelectedArea}">
            <CollectionView.ItemTemplate>
                <DataTemplate x:DataType="models:Area">
                    <controls:AreaView Area="{Binding .}"/>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
        <Button Text="Select Random"
                Command="{Binding SelectRandomCommand}"/>
    </StackLayout>
</ContentPage>

ViewModel

public partial class WorldViewModel : ObservableObject
{
    public ObservableCollection<Area> Areas { get; set; }
    [ObservableProperty]
    public Area selectedArea;

    private readonly WorldService _worldService;
    private readonly World _world;

    public WorldViewModel(WorldService worldService)
    {
        _worldService = worldService;
        _world = _worldService.Get(0);
        Areas = new ObservableCollection<Area>(_world.Areas);
        SelectedArea = _world.Areas.Single(x => x.X == 1 && x.Y == 1);
    }
    [RelayCommand]
    void SelectRandom()
    {
        var random = new Random().Next(Areas.Count);
        SelectedArea = Areas[random];
    }
}

The custom control above the collection view, display more details of the selected area. It's binded to SelectedArea property.

I would like that when I click on an area, the display view is updated with the one I clicked on.

Sceenshot of the app to help understanding.

enter image description here

like image 915
Cedric Royer-Bertrand Avatar asked Sep 05 '25 08:09

Cedric Royer-Bertrand


1 Answers

So I finally found an open bug In the MAUI repo that says CollectionView's SelectionChanged method cannot be triggered when tapping the item directly see https://github.com/dotnet/maui/issues/9567

It's on open bug that is affecting Android and will be fix later (it's in the backlog asof Aug 2023).

The workaround is to not use Frame. So I change the data Template in my collection view

            <CollectionView.ItemTemplate>
                <DataTemplate x:DataType="models:Area">
                    <controls:AreaView Area="{Binding .}"/>
                </DataTemplate>
            </CollectionView.ItemTemplate>

To not use Frame...I just used a StackLayout

<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Maui.Controls.AreaView"
             xmlns:converters="clr-namespace:Maui.Converters"
             x:Name="this">
    <ContentView.Resources>
        <converters:AreaTypeConverter x:Key="AreaTypeConverter" />
    </ContentView.Resources>
    <StackLayout BindingContext="{x:Reference this}" BackgroundColor="{Binding Area.Type, Converter={StaticResource AreaTypeConverter}}">
        <Label>
            <Label.FormattedText>
                <FormattedString>
                    <Span Text="("/>
                    <Span Text="{Binding Area.X}"/>
                    <Span Text=","/>
                    <Span Text="{Binding Area.Y}"/>
                    <Span Text=")"/>
                </FormattedString>
            </Label.FormattedText>
        </Label>
    </StackLayout>
</ContentView>
like image 132
Cedric Royer-Bertrand Avatar answered Sep 07 '25 23:09

Cedric Royer-Bertrand