Search code examples
c#xamlxamaringridviewcross-platform

ListView Highlight Selected Item Color is not staying on when selected other buttons


I have this ListView with 2 buttons, on each List/Item (Plus and Minus Buttons) that appears only on selected item. In addition to those buttons, the selected item will also change the color to LightGray and the previews item will be Transparent (which is working great).

But the problem I have is when I select an Item and then click on the Plus / Minus Button, it’s clearing the selected item color. So only the buttons will stay on, but the BackgroundColor is gone.

I’m trying to keep the LightGray color all the time until I select a different item.

Since I’m new to this It will be great if you can help me with some example (If possible please).

If need more Info, please let me know.

Thank you so much.

ItemsPage.xaml

<ListView ItemsSource="{Binding Items, Mode=TwoWay}" x:Name="lstView" SelectedItem="{Binding SelectedItem}" HasUnevenRows="True" RowHeight="50">
  <ListView.ItemTemplate>
    <DataTemplate>
      <ViewCell>
        <Grid Padding="0,0,8,0" Margin="4,0,4,0">
          <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="7*"/>
          </Grid.ColumnDefinitions>

          <Grid.GestureRecognizers>
            <TapGestureRecognizer NumberOfTapsRequired="1" Tapped="TapGestureRecognizer_Edit1" CommandParameter="{Binding ItemId}"/>
          </Grid.GestureRecognizers>

          <Label Text="{Binding ItemName}" Grid.Column="1" FontSize="Medium"></Label>
           
          <Image Source="DecreaseIcon1.png" Grid.Column="2" Margin="4" IsVisible="{Binding IsVisible}">
            <Image.GestureRecognizers>
              <TapGestureRecognizer Tapped="DecrementQuantity" CommandParameter="{Binding ItemId}"/>
            </Image.GestureRecognizers>
          </Image>

          <Entry Text="{Binding ItemQuantity}" Grid.Column="3" VerticalTextAlignment="Center"/>

          <Image Source="IncreaseIcon1.png" Grid.Column="4" Margin="4" IsVisible="{Binding IsVisible}">
            <Image.GestureRecognizers>
              <TapGestureRecognizer Tapped="IncrementQuantity" CommandParameter="{Binding ItemId}"/>
            </Image.GestureRecognizers>
          </Image>

        </Grid>
      </ViewCell>
    </DataTemplate>
  </ListView.ItemTemplate>
</ListView>

ItemsPage.cs

private void IncrementQuantity(object sender, EventArgs e)
  {
    TappedEventArgs tappedEventArgs = (TappedEventArgs)e;
    Item item = ((ItemViewModel)BindingContext).Items.Where(x => x.ItemId == (Guid)tappedEventArgs.Parameter).FirstOrDefault();

    var oldQuantity = item.ItemQuantity++;
  }

private void DecrementQuantity(object sender, EventArgs e)
  {
    TappedEventArgs tappedEventArgs = (TappedEventArgs)e;
    Item item = ((ItemViewModel)BindingContext).Items.Where(x => x.ItemId == (Guid)tappedEventArgs.Parameter).FirstOrDefault();

    var oldQuantity = item.ItemQuantity--;
  }

Grid lastGrid;
private void TapGestureRecognizer_Edit1(object sender, EventArgs e)
  {
    TappedEventArgs tappedEventArgs = (TappedEventArgs)e;
    Item item = ((ItemViewModel)BindingContext).Items.Where(x => x.ItemId == (Guid)tappedEventArgs.Parameter).FirstOrDefault();
    _item = item;

    var grid = sender as Grid;
    lstView.SelectedItem = grid.BindingContext;

    if (lastGrid != null)
    {
    lastGrid.BackgroundColor = Color.Transparent;
    }
    var viewCell = (Grid)sender;
    if (viewCell.BackgroundColor != null)
    {
    viewCell.BackgroundColor = Color.LightGray;
    lastGrid = viewCell;
    }
  }

Solution

  • According to your description, I suggest you can use CollectionView to replace ListView. Then using Xamarin.Forms Visual State Manager to highlight selecteditem backgroundcolor.

    This is VisualStateManager in ContentPage.Resource.

     <ContentPage.Resources>
       
        <Style x:Key="stacklayoutStyle" TargetType="StackLayout">
            <Setter Property="VisualStateManager.VisualStateGroups">
                <VisualStateGroupList>
                    <VisualStateGroup x:Name="CommonStates">
                        <VisualState x:Name="Normal" />
    
                        <VisualState x:Name="Selected">
                            <VisualState.Setters>
                                <Setter Property="BackgroundColor" Value="LightGray" />
                            </VisualState.Setters>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateGroupList>
            </Setter>
        </Style>
    </ContentPage.Resources>
    

    Using this style in CollectionView.The selected state will stay on when you click Button.

     <CollectionView ItemsSource="{Binding items}" SelectionMode="Single">
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <StackLayout Style="{StaticResource stacklayoutStyle}">
                            <Grid Margin="4,0,4,0" Padding="0,0,8,0">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto" />
                                    <ColumnDefinition Width="Auto" />
                                    <ColumnDefinition Width="Auto" />
                                    <ColumnDefinition Width="Auto" />
                                </Grid.ColumnDefinitions>
                                <Label
                                    Grid.Column="1"
                                    FontSize="Medium"
                                    Text="{Binding ItemName}" />
                                <Button Grid.Column="2" Text="decrement" />
                                <Entry
                                    Grid.Column="3"
                                    Text="{Binding ItemQuantity}"
                                    VerticalTextAlignment="Center" />
                                <Button Grid.Column="4" Text="Increment" />
                            </Grid>
                           
                        </StackLayout>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
    
            </CollectionView>