Selection in Xamarin ListView (SfListView)

This section explains how to perform selection and its related operations in the SfListView.

UI selection

The SfListView allows selecting items either programmatically or touch interactions by setting the SfListView.SelectionMode property value to other than None. The control has different selection modes to perform selection operations as listed as follows:

  • None: Allows disabling selection.
  • Single: Allows selecting single item only. When clicking on the selected item, selection not will not be cleared. This is the default value for SfListView.SelectionMode.
  • SingleDeselect: Allows selecting single item only. When clicking on the selected item, selection gets cleared.
  • Multiple: Allows selecting more than one item. Selection is not cleared when selecting more than one items. When clicking on the selected item, selection gets cleared.

The SfListView allows selecting items on different gestures such as tap, double tap, and hold by setting the SfListView.SelectionGesture. The default value for the SfListView.SelectionGesture is TouchGesture.Tap.

<syncfusion:SfListView x:Name="listView"
                        SelectionMode="Multiple"
                        SelectionGesture="Hold"/>
listView.SelectionMode = SelectionMode.Multiple;
listView.SelectionGesture = TouchGesture.Hold;

Single item selection in listview

Programmatic selection

When the SfListView.SelectionMode is other than None, the item or items in the SfListView can be selected from the code by setting the SfListView.SelectedItem, or adding items to the SfListView.SelectedItems property based on the SfListView.SelectionMode.

When the selection mode is Single, programmatically select an item by setting the underlying object to the SfListView.SelectedItem property.

//Perform selection using selected item
listView.SelectedItem = viewModel.Items[5];

When the selection mode is Multiple, programmatically select more than one item by adding the underlying object to the SfListView.SelectedItems property.

//Perform multiple selection using selected items
listView.SelectedItems.Add (viewModel.Items [4]);
listView.SelectedItems.Add (viewModel.Items[5]);

All items of the SfListView can be selected using the SelectAll method.

listView.SelectAll();

NOTE

When programmatically select an item then the selection related events will not be triggered. It triggers only on UI interactions.
However, get the notification from the SelectedItems collection changed event which will be triggered when add an item at runtime.

Selected items

Get selected items

The SfListView gets all the selected items through the SfListView.SelectedItems property and gets the single item by using the SfListView.SelectedItem property.

Clear selected items

The selected items can be cleared by calling the SelectedItems.Clear() method.

listView.SelectedItems.Clear();

CurrentItem vs SelectedItem

The SfListView gets the selected item by using the SfListView.SelectedItem and SfListView.CurrentItem properties. Both SfListView.SelectedItem and SfListView.CurrentItem returns the same data object when selecting single item. When selecting more than one item, the SfListView.SelectedItem property returns the first selected item, and the SfListView.CurrentItem property returns the last selected item.

WARNING

If you select an item when SfListView.SelectionMode is none or if you select multiple items when SfListView.SelectionMode is single, exception will be thrown.

Selected item customization

The SfListView supports customizing the selection background color for the selected items by using the SfListView.SelectedItemTemplate if the background color is set to view loaded in the SfListView.ItemTemplate.

<ContentPage  xmlns:syncfusion="clr-namespace:Syncfusion.ListView.XForms;assembly=Syncfusion.SfListView.XForms">
  <syncfusion:SfListView x:Name="listView">
   <syncfusion:SfListView.SelectedItemTemplate>
    <DataTemplate>
     <Grid x:Name="grid" BackgroundColor="RoyalBlue">
      <Grid.RowDefinitions>
         <RowDefinition Height="*" />
         <RowDefinition Height="*" />
         <RowDefinition Height="1" />
       </Grid.RowDefinitions>
      <Label Text="{Binding SongTitle}" />
      <Label Text="{Binding SongAuther}" Grid.Row="1"/>
      <Frame Grid.Row="2" HasShadow="True" HeightRequest="1"/>
     </Grid>
    </DataTemplate>
   </syncfusion:SfListView.SelectedItemTemplate>
  </syncfusion:SfListView>
</ContentPage>
listView.SelectedItemTemplate = new DataTemplate(() =>
{
  var grid = new Grid();
  grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
  grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
  grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1) });
  grid.BackgroundColor = Color.RoyalBlue;
  var songTitle = new Label();
  songTitle.SetBinding(Label.TextProperty, new Binding("SongTitle"));
  var songAuthor = new Label();
  songAuthor.SetBinding(Label.TextProperty, new Binding("songAuthor"));
  var frame = new Frame()
  {
    HeightRequest = 1,
    HasShadow = true,
  };
  grid.Children.Add(songTitle);
  grid.Children.Add(songAuthor, 0, 1);
  grid.Children.Add(frame, 0, 2);
  return grid;
});

Download the entire sample from GitHub here.

Custom selection in listview

Show checked circle on selected items

To customize the appearance of the selected item or items by using the appearance of SfListView.SelectedItemTemplate. The following customizations should give an idea to customize the appearance of selected items in the control.

<ContentPage xmlns:syncfusion="clr-namespace:Syncfusion.ListView.XForms;assembly=Syncfusion.SfListView.XForms">
  <syncfusion:SfListView x:Name="listView">
   <syncfusion:SfListView.SelectedItemTemplate>
    <DataTemplate>
     <Grid x:Name="grid">
      <Grid.ColumnDefinitions>
       <ColumnDefinition Width="40" />
       <ColumnDefinition Width="*" />    
       <ColumnDefinition Width="Auto" />
      </Grid.ColumnDefinitions>
      <Image Source="{Binding SongThumbnail}"/>
      <Grid Grid.Column="1">
       <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
       </Grid.RowDefinitions>
       <Label Text="{Binding SongTitle}" />
       <Grid Grid.Row="1">
        <Grid.ColumnDefinitions>
         <ColumnDefinition Width="*" />
         <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Label Text="{Binding SongAuther}" />
        <Label Grid.Column="1" Text="{Binding SongSize}"/>
       </Grid>
      </Grid>
      <Image Grid.Column="2" x:Name="selectionImage" IsVisible="True" Source="Selected.png"/>
     </Grid>
    </DataTemplate>
   </syncfusion:SfListView.SelectedItemTemplate>
  </syncfusion:SfListView>
</ContentPage>
listView.SelectedItemTemplate = new DataTemplate(() =>
{
  var grid1 = new Grid();
  grid1.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(40) });
  grid1.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
  grid1.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) });
  var songThumbnail = new Image();
  songThumbnail.SetBinding(Image.SourceProperty, new Binding("SongThumbnail"));
  var grid2 = new Grid();
  grid2.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
  grid2.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
  grid2.Padding = new Thickness(15, 0, 0, 0);
  var songTitle = new Label();
  songTitle.SetBinding(Label.TextProperty, new Binding("SongTitle"));
  var grid3 = new Grid();
  grid3.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
  grid3.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
  var songAuthor = new Label();
  songAuthor.SetBinding(Label.TextProperty, new Binding("songAuthor"));
  var songSize = new Label();
  songSize.SetBinding(Label.TextProperty, new Binding("SongSize"));
  grid3.Children.Add(songAuthor);
  grid3.Children.Add(songSize, 1, 0);
  grid2.Children.Add(songTitle);
  grid2.Children.Add(grid3, 0, 1);
  var selectionImage = new Image()
  {
    IsVisible = true,
    Source = "Selected.png"
  };
  grid1.Children.Add(songThumbnail);
  grid1.Children.Add(grid2, 1, 0);
  grid1.Children.Add(selectionImage, 2, 0);
  return grid1;
});

Download the entire source code from GitHub here.

Multiple item selection in listview

Selected item style

Selection in Xamarin ListView (SfListView) background

The SfListView allows changing the selection background color for the selected items by using the SfListView.SelectionBackgroundColor property. You can also change the selection background color at runtime.

<syncfusion:SfListView x:Name="listView"
                        SelectionBackgroundColor="Khaki"/>
listView.SelectionBackgroundColor = Color.Khaki;

Selection background color in listview

Programmatic animation

The SfListView allows programmatic animation in selection at runtime by using the virtual method AnimateSelectedItem of SelectionController class.

listView.SelectionController = new SelectionControllerExt(listView);

public class SelectionControllerExt : SelectionController
{
   public SelectionControllerExt(SfListView listView) : base(listView)
   {
   }
   
   protected override void AnimateSelectedItem(ListViewItem selectedListViewItem)
   {
      base.AnimateSelectedItem(selectedListViewItem);
      selectedListViewItem.Opacity = 0;
      selectedListViewItem.FadeTo(1, 3000, Easing.SinInOut);
   }
}

Download the entire source code from GitHub here.

Selection animation in listview

Events

Selection in Xamarin ListView (SfListView)Changing event

The SelectionChanging event is raised while selecting an item at the execution time. ItemSelectionChangingEventArgs has the following members which provides the information for SelectionChanging event:

  • AddedItems: Gets collection of the underlying data objects where the selection is going to process.
  • RemovedItems: Gets collection of the underlying data objects where the selection is going to remove.

You can cancel the selection process within this event by setting the ItemSelectionChangingEventArgs.Cancel property to true.

The SelectionChanging event is used for the following use case:

  • Disable the selection of the particular item based on the underlying data.
listView.SelectionChanging += ListView_SelectionChanging;  

private void ListView_SelectionChanging(object sender, ItemSelectionChangingEventArgs e)
{
  if (e.AddedItems.Count > 0 && e.AddedItems[0] == ViewModel.Items[0])
      e.Cancel = true;
}

Selection in Xamarin ListView (SfListView)Changed event

The SelectionChanged event will occur once selection process has been completed for the selected item in the SfListView. ItemSelectionChangedEventArgs has the following members which provides information for SelectionChanged event:

  • AddedItems: Gets collection of the underlying data objects where the selection has been processed.
  • RemovedItems: Gets collection of the underlying data objects where the selection has been removed.

The SelectionChanged event used for the following use cases:

  • Clears all the selected item.
  • Removes the particular selected item.
  • Gets the index of the selected item.
listView.SelectionChanged += ListView_OnSelectionChanged;  

private void ListView_OnSelectionChanged(object sender, ItemSelectionChangedEventArgs e)
{
   listView.SelectedItems.Clear();
}

NOTE

SelectionChanging and SelectionChanged events will be triggered only on UI interactions.

Key navigation

The AllowKeyNavigation property enables navigation through keyboard buttons. When the AllowKeyNavigation property is true, navigation gets enabled. Otherwise, set to false. Behavior of key navigation in UWP and macOS are explained as follows :

  • When the SfListView.SelectionMode is Single, the selected item is highlighted with FocusBorderColor around the item while key navigation.
  • When the SelectionMode is SingleDeSelect or Multiple, the FocusBorderColor will set to the CurrentItem only on key navigation.
  • If focusable elements i.e. Entry, SearchBar, etc. are loaded in the page, the Focus will not be changed either to other elements in the view or to the next ListViewItem when Tab or Shift+Tab key is pressed in the LinearLayout.
  • In the GridLayout with span count greater than 1, the FocusBorderColor will navigate to the next or previous ListViewItem when pressing Tab or Shift+Tab key.
  • In macOS, need to move the focus manually to perform key navigation.

FocusBorderColor

FocusBorderColor used to set the border color for the current focused item. For Android and iOS platform, the default color is Color.Transparent and for macOS and UWP platform, the default color is Color.FromRgb(76, 161, 254).

FocusBorderThickness

FocusBorderThickness used to set the border thickness for the current focused item. For Android and iOS platform, the default thickness is 0 and for macOS and UWP platform, the default thickness is 1.

MacOS support

Known issues

  • If SfListView flings with more inertia or the scrollbar reaches either the bottom or top of the view, the listview items will not layout properly. Since, it occurs in simple custom control and Xamarin.Forms.ListView. So, a defect report is logged to Bugzilla team. Find the bug report: https://github.com/xamarin/Xamarin.Forms/issues/2403
  • When Grouping is enabled, the listview items and group header items will not layout properly while scrolling the SfListView.
  • Application will get crash when Linker option is set as Link All.
  • If an Image is loaded in the ItemTemplate property, it is necessary to define a definite size for the Image.

Not yet implemented

The following features are not yet implemented due to some limitations in the Xamarin.Forms.macOS platform:

How to

Disable selection on particular item

The selection of a particular set of items can be disabled based on the SfListView.SelectedItems of the underlying collections.

public partial class MainPage : ContentPage
{
  public MainPage()
  {
    InitializeComponent();
  }

  private void listView_SelectionChanging(object sender, Syncfusion.ListView.XForms.ItemSelectionChangingEventArgs e)
  {
  if (e.AddedItems.Count > 0 && (e.AddedItems[0] as Contacts).Category == "Non-Selectable items")
      e.Cancel = true;
  }
}

Download the entire sample from GitHub here.

Automatically scroll to bring a selected item into the view

To bring the SfListView.SelectedItem automatically into the view when it changed at runtime by calling the ScrollToRowIndex method.

In linear layout, you can get the row index of SfListView.SelectedItem and resolve if header and group header are used.

public partial class MainPage : ContentPage
{
  public MainPage()
  {
    InitializeComponent();
    listView.PropertyChanged += listView_PropertyChanged;
  }

  private void listView_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
  {
    if (e.PropertyName == "SelectedItem")
    {
       var selectedItemIndex = listView.DataSource.DisplayItems.IndexOf(listView.SelectedItem);
       selectedItemIndex += (listView.HeaderTemplate != null && !listView.IsStickyHeader || !listView.IsStickyGroupHeader) ? 1 : 0;
       selectedItemIndex -= (listView.GroupHeaderTemplate != null && listView.IsStickyGroupHeader) ? 1 : 0;
       (listView.LayoutManager as LinearLayout).ScrollToRowIndex(selectedItemIndex);
    }
  }
}

Download the entire sample from GitHub here.

Gets the index of selected item

When performing selection, you can get the index of the selected item by using the SelectionChanged event from the DataSource.DisplayItems.

public partial class MainPage : ContentPage
{
  public MainPage()
  {
    InitializeComponent();
    listView.SelectionChanged += ListView_SelectionChanged;
  }

  private void ListView_SelectionChanged(object sender, ItemSelectionChangedEventArgs e)
  {
    var items = e.AddedItems;
    var index = listView.DataSource.DisplayItems.IndexOf(items[0]);
    entry.Text = index.ToString();
  }
}

Download the entire sample from GitHub here.

Display selection when ItemTemplate contains image

When ItemTemplate contains only image, then the selection color will not be visible in the view when select an image. To see selection, add any layout such as Grid or StackLayout above the image, and set margin or padding to it.

<ContentPage xmlns:syncfusion="clr-namespace:Syncfusion.ListView.XForms;assembly=Syncfusion.SfListView.XForms">
  <syncfusion:SfListView
   ItemsSource="{Binding BookInfo}"
   ItemSize="100">  
    <syncfusion:SfListView.ItemTemplate>  
        <DataTemplate>  
            <Grid Margin="10">  
                <Image Source="{Binding Image}" Aspect="Fill"/>  
            </Grid>  
        </DataTemplate>  
    </syncfusion:SfListView.ItemTemplate>  
</syncfusion:SfListView>  
</ContentPage>
public partial class MainPage : ContentPage
{
    SfListView listView;
    public MainPage()
    {
        InitializeComponent();
        listView = new SfListView();
        listView.ItemSize = 100;
        listView.ItemsSource = viewModel.BookInfo;
        listView.ItemTemplate = new DataTemplate(() =>
        {
            var grid = new Grid() { Margin = 10 };
            var image = new Image() { Aspect = Aspect.Fill};
            image.SetBinding(Image.SourceProperty, new Binding("Image"));
            grid.Children.Add(image);
            return grid;
        });
        this.Content = listView;
    }
}

Limitation

  • When a grid is loaded inside the ItemTemplate with background color, the SelectionBackgroundColor will not display. Because, it overlaps the SelectionBackgroundColor. In this case, set the background color for the ListView instead of ItemTemplate.
  • When the ListView contains duplicated items in the collection, only the first item whose instance was created initially will be selected or deselected.