windowsmauiobservablecollectionmaui-collectionview

MAUI CollectionView Selected style only works on first item


I'm using an example from Configure CollectionView item selection in my app, but the background color only changes when the first item in the observable collection is selected. First Item selected:

enter image description here

Other item selected:

enter image description here

The code in Style.xaml:

<Style TargetType="Grid">
<Setter Property="VisualStateManager.VisualStateGroups">
    <VisualStateGroupList>
        <VisualStateGroup x:Name="CommonStates">
            <VisualState x:Name="Normal" />
            <VisualState x:Name="Selected">
                <VisualState.Setters>
                    <Setter Property="BackgroundColor" Value="Blue" />
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateGroupList>
</Setter>

The code in my page:

<CollectionView Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="6" Grid.RowSpan="5" ItemsSource="{Binding Items}" Margin="40" SelectionMode="Single" SelectionChanged="CollectionView_SelectionChanged">
<CollectionView.ItemTemplate>
    <DataTemplate x:DataType="model:ItemsModel">
        <Grid ColumnDefinitions="40, 80, 40, *">
            <Label Grid.Column="0" Text="{Binding PlanOrder, StringFormat='{0:00}'}" TextColor="{StaticResource Cyan}" />
            <Label Grid.Column="1" Text="Item" TextColor="{StaticResource Cyan}" />
            <Label Grid.Column="2" Text="{Binding DestNumber, StringFormat='{0:00}'}" TextColor="{StaticResource Cyan}" />
        </Grid>
    </DataTemplate>
</CollectionView.ItemTemplate>

I put the visual state on the Style.xaml file as I have multiple CollectionView in the app that would use this state. Even in the other CollectionView, the same thing is happening.


Solution

  • I remember I had a similar issue and I ended up doing a workaround I'm pretty happy with.

    In my model, I add a property like this to indicate the item is selected:

    [ObservableProperty]
    public partial bool IsSelected { get; set; }
    

    In the xaml you can use it to change your views based on the IsSelected property, for example:

    <Border
         Stroke="{Binding IsSelected, Converter={StaticResource SelectedToStrokeColorConverter}}"
    

    In the example I use a converter from the MAUI community toolkit to provide the color resource:

    <toolkit:BoolToObjectConverter
        x:Key="SelectedToStrokeColorConverter"
        FalseObject="{StaticResource TransparantColor}"
        TrueObject="{StaticResource SelectedColor}" />
    

    You can use the SelectionChanged event or command on your collectionview in combination with the CollectionView.SelectedItem to updated the IsSelected property.