ListView Interactivity

Download Sample Download the sample

ListView supports interacting with the data it presents.

Selection & Taps

The ListView selection mode is controlled by setting the ListView.SelectionMode property to a value of the ListViewSelectionMode enumeration:

  • Single indicates that a single item can be selected, with the selected item being highlighted. This is the default value.
  • None indicates that items cannot be selected.

When a user taps an item, two events are fired:


Tapping the same item twice will fire two ItemTapped events, but will only fire a single ItemSelected event.

When the SelectionMode property is set to Single, items in the ListView can be selected, the ItemSelected and ItemTapped events will be fired, and the SelectedItem property will be set to the value of the selected item.

When the SelectionMode property is set to None, items in the ListView cannot be selected, the ItemSelected event will not be fired, and the SelectedItem property will remain null. However, ItemTapped events will still be fired and the tapped item will be briefly highlighted during the tap.

When an item has been selected and the SelectionMode property is changed from Single to None, the SelectedItem property will be set to null and the ItemSelected event will be fired with a null item.

The following screenshots show a ListView with the default selection mode:

Disabling Selection

To disable ListView selection set the SelectionMode property to None:

<ListView ... SelectionMode="None" />
var listView = new ListView { ... SelectionMode = ListViewSelectionMode.None };

Context Actions

Often, users will want to take action on an item in a ListView. For example, consider a list of emails in the Mail app. On iOS, you can swipe to delete a message::

Context actions can be implemented in C# and XAML. Below you'll find specific guides for both, but first let's take a look at some key implementation details for both.

Context Actions are created using MenuItems. Tap events for MenuItems are raised by the MenuItem itself, not the ListView. This is different from how tap events are handled for cells, where the ListView raises the event rather than the cell. Because the ListView is raising the event, its event handler is given key information, like which item was selected or tapped.

By default, a MenuItem has no way of knowing which cell it belongs to. CommandParameter is available on MenuItem to store objects, such as the object behind the MenuItem's ViewCell. CommandParameter can be set in both XAML and C#.


Context actions can be implemented in any Cell subclass (as long as it isn't being used as a group header) by creating MenuItems and adding them to the ContextActions collection for the cell. You have the following properties can be configured for the context action:

  • Text – the string that appears in the menu item.
  • Clicked – the event when the item is clicked.
  • IsDestructive – (optional) when true the item is rendered differently on iOS.

Multiple context actions can be added to a cell, however only one should have IsDestructive set to true. The following code demonstrates how context actions would be added to a ViewCell:

var moreAction = new MenuItem { Text = "More" };
moreAction.SetBinding (MenuItem.CommandParameterProperty, new Binding ("."));
moreAction.Clicked += async (sender, e) => {
    var mi = ((MenuItem)sender);
    Debug.WriteLine("More Context Action clicked: " + mi.CommandParameter);

var deleteAction = new MenuItem { Text = "Delete", IsDestructive = true }; // red background
deleteAction.SetBinding (MenuItem.CommandParameterProperty, new Binding ("."));
deleteAction.Clicked += async (sender, e) => {
    var mi = ((MenuItem)sender);
    Debug.WriteLine("Delete Context Action clicked: " + mi.CommandParameter);
// add to the ViewCell's ContextActions property
ContextActions.Add (moreAction);
ContextActions.Add (deleteAction);


MenuItems can also be created in a XAML collection declaratively. The XAML below demonstrates a custom cell with two context actions implemented:

<ListView x:Name="ContextDemoList">
            <MenuItem Clicked="OnMore" CommandParameter="{Binding .}"
               Text="More" />
            <MenuItem Clicked="OnDelete" CommandParameter="{Binding .}"
               Text="Delete" IsDestructive="True" />
         <StackLayout Padding="15,0">
              <Label Text="{Binding title}" />

In the code-behind file, ensure the Clicked methods are implemented:

public void OnMore (object sender, EventArgs e) {
    var mi = ((MenuItem)sender);
    DisplayAlert("More Context Action", mi.CommandParameter + " more context action", "OK");

public void OnDelete (object sender, EventArgs e) {
    var mi = ((MenuItem)sender);
    DisplayAlert("Delete Context Action", mi.CommandParameter + " delete context action", "OK");


The NavigationPageRenderer for Android has an overridable UpdateMenuItemIcon method that can be used to load icons from a custom Drawable. This override makes it possible to use SVG images as icons on MenuItem instances on Android.

Pull to Refresh

Users have come to expect that pulling down on a list of data will refresh that list. ListView supports this out-of-the-box. To enable pull-to-refresh functionality, set IsPullToRefreshEnabled to true:

<ListView ...
          IsPullToRefreshEnabled="true" />

The equivalent C# code is:

listView.IsPullToRefreshEnabled = true;

A spinner appears during the refresh, which is black by default. However, the spinner color can be changed on iOS and Android by setting the RefreshControlColor property to a Color:

<ListView ...
          RefreshControlColor="Red" />

The equivalent C# code is:

listView.RefreshControlColor = Color.Red;

The following screenshots show pull-to-refresh as the user is pulling:

The following screenshots show pull-to-refresh after the user has released the pull, with the spinner being shown while the ListView is updating:

ListView fires the Refreshing event to initiate the refresh, and the IsRefreshing property will be set to true. Whatever code is required to refresh the contents of the ListView should then be executed by the event handler for the Refreshing event, or by the method executed by the RefreshCommand. Once the ListView is refreshed, the IsRefreshing property should be set to false, or the EndRefresh method should be called, to indicate that the refresh is complete.


When defining a RefreshCommand, the CanExecute method of the command can be specified to enable or disable the command.