2
votes

how can I change the selected color of a list view selected item in Xamarin Forms Cross Platform?

I was able to change it using the answer in this question How can I change background color of a ListView in Xaml?

but on first appear the selected item is with the default background color (Orange).

Any suggestions?

I wonder why in 2019 (nearly 2020) there isn't an out of the box way to change this basic and common property easly.

Thanks.

2

2 Answers

2
votes

The below code works perfectly for me. However, it iterates the entire ItemsSource for resetting the background of the previously selected item. You can store it and reset it if you wish to optimize it. Hope this helps.

<ListView x:Name="contactList" ItemsSource="{Binding PlatformsList}" ItemTapped="contactList_ItemTapped"
             VerticalOptions="CenterAndExpand" HorizontalOptions="FillAndExpand">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <Label TextColor="Black" Margin="10,0" Text="{Binding PlatformName}" BackgroundColor="{Binding Background}" VerticalOptions="Center" />
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

private void contactList_ItemTapped(object sender, ItemTappedEventArgs e)
{
    var selectedItem = e.Item as PlatformInfo;
    selectedItem.ItemBackground = Color.Aqua;

    foreach(var item in this.contactList.ItemsSource)
    {
        if (item != selectedItem)
            (item as PlatformInfo).ItemBackground = Color.Transparent;
    }
}
0
votes

I chose to avoid using the ListViews's ItemSelected event or custom renderer approach and apply style changes in the code behind file. The Tapped gesture event and a list (SelectedItems) for tracking the views contained within the active list item, provides easy color style changes.

.xaml file

<ListView ItemsSource="{Binding ViewModelList}" SelectionMode="None">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <Grid Padding="10">
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="*" />
                                </Grid.RowDefinitions> 
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto" />
                                    <ColumnDefinition Width="*" />
                                </Grid.ColumnDefinitions>                                   
                                <Label Grid.Row="0" Grid.Column="0" Text="{Binding CNumber'}">
                                    <Label.GestureRecognizers>
                                        <TapGestureRecognizer Tapped="Tapped_Command" CommandParameter="{Binding CNumber}" />
                                    </Label.GestureRecognizers>
                                </Label>
                                <Label Grid.Row="0" Grid.Column="1" Text="{Binding Brand}" TextColor="{StaticResource Blue}">
                                    <Label.GestureRecognizers>
                                        <TapGestureRecognizer Tapped="Tapped_Command" CommandParameter="{Binding CNumber}" />
                                    </Label.GestureRecognizers>
                                </Label>
                            </Grid>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>

.xaml.cs code behind file

 private List<View> SelectedItems { get; set; }

    public MYListPage()
    {
        InitializeComponent();           
        BindingContext = new MyViewModel();
        SelectedItems = new List<View>();
    }


       private async void Tapped_Command(object sender, EventArgs e)
    {
        var l = (Label)sender;
        var cNumber= (((TappedEventArgs)e).Parameter) as string;
        if (string.IsNullOrEmpty(contract))
            await DisplayAlert("Error", "Could not load the information", "close");
        else
        {
            if (SelectedItems.Count > 0)
            {
                foreach (var v in SelectedItems)  //reset the styling to the original 'unselected' colors
                {
                    if (v.GetType() == typeof(Grid))
                        ((Grid) v).BackgroundColor = Color.Transparent;
                    else if(v.GetType() == typeof(Label))
                        ((Label)v).TextColor = Color.Black;
                }
                SelectedItems.Clear();
            }
            var parent = (Grid)l.Parent;
            parent.BackgroundColor = Color.FromHex("#E0E0E0");   //set the background color
            SelectedItems.Add(parent);
            foreach (var c in parent.Children)   //option to set additional styling to the child elements
            {
                var child = (Label)c;
                child.TextColor = Color.FromRgb(0, 123, 255);
                SelectedItems.Add(child);
            }
            await Navigation.PushAsync(new MyDetailsPage(viewModel, cNumber));
        }
    }