Search code examples
xamlxamarin.formsselecteditemxamarin.forms.collectionview

CollectionView GridItemsLayout Change BackgroundColor of nested Item (Button)


I have a problem concerning a CollectionView with a GridItemsLayout. In my application, I have a StackLayout with a horizontal CollectionView(GridItemsLayout), which contains a Button bound to a certain category.

Whenever a button is clicked/tapped, it filters the ListView (of type Surgery) below based on the category. All of that is working fine, however, I would like to highlight the Category/Button by changing it BackgroundColor to see which category is currently used for filtering.

<CollectionView HeightRequest="70"
                    x:Name="categoryCollection"
                    ItemsSource="{Binding Categories}"
                    Margin="20,0,20,0"
                    SelectionMode="Single">
        <CollectionView.ItemsLayout>
            <GridItemsLayout Orientation="Horizontal" Span="1" HorizontalItemSpacing="5"/>
        </CollectionView.ItemsLayout>
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <Grid Padding="0,5,0,5">
                    <Button x:Name="categoryButton" Text="{Binding Name}" 
                            Command="{Binding Path=BindingContext.FilterCommand, Source={x:Reference Name=SurgeryListView}}"
                            CommandParameter="{Binding .}"
                            CornerRadius="15"
                            FontFamily="OpenSans" Margin="0,5,10,5"
                            Opacity="0.6" FontSize="16" TextTransform="None">
                    </Button>
                </Grid>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>

 <ListView x:Name="listView"
              ItemsSource="{Binding Surgeries}"
              RefreshCommand="{Binding LoadSurgeriesCommand}"
              IsRefreshing="{Binding IsRefreshing}"
              IsPullToRefreshEnabled="True"
              RowHeight="70"
              BackgroundColor="{StaticResource darkThemeBackground}"
              ItemTemplate="{StaticResource surgeryDataTemplateSelector}">

        <ListView.Behaviors>
            <behaviors:EventToCommandBehavior
                EventName="ItemTapped"
                Command="{Binding SurgerySelectedCommand}"
                EventArgsConverter="{StaticResource ItemTappedConverter}">
            </behaviors:EventToCommandBehavior>
        </ListView.Behaviors>
    </ListView>

I tried to use VisualStates but that was not working, because tapping the button does not actually change the SelectedItem (one would need to click the surrounding/parent grid element for that). Moreover, the altered VisualState was only applied to the Grid's BackgroundColor, not to that of the actual button.

Question: How can I highlight the current Category/Button by changing its Background Color?


Solution

  • Since the selection is working good, remains only the ui/xaml part, if you look at the documentation about VisualStateManager, you can add the following style:

    <CollectionView.Resources>
                    <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="LightSkyBlue" />
                                        </VisualState.Setters>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateGroupList>
                        </Setter>
                    </Style>
    </CollectionView.Resources>