ListView Interactivity

ListView supports interacting with the data it presents through the following means:

  • Selection & Taps – respond to taps and selections/deselections of items. Enable or disable row selection (enabled by default).
  • Context Actions – Expose functionality per item, for example, swipe-to-delete.
  • Pull-to-Refresh – Implement the pull-to-refresh idiom that users have come to expect from native experiences.

Selection & Taps

ListView supports selection of one item at a time. Selection is on by default. When a user taps an item, two events are fired: ItemTapped and ItemSelected. Note that tapping the same item twice will not fire multiple ItemSelected events, but will fire multiple ItemTapped events. Also note that ItemSelected will be called if an item is deselected.

Be aware that ItemSelected is called both when items are deselected and when they are selected. That means you'll need to check for null SelectedItem in your ItemSelected event handler before you can use it:

void OnSelection (object sender, SelectedItemChangedEventArgs e)
  if (e.SelectedItem == null) {
    return; //ItemSelected is called on deselection, which results in SelectedItem being set to null
  DisplayAlert ("Item Selected", e.SelectedItem.ToString (), "Ok");
  //((ListView)sender).SelectedItem = null; //uncomment line if you want to disable the visual selection state.

Disabling Selection

If you want to disable selection, handle the ItemSelected event and set the SelectedItem property to null:

SelectionDemoList.ItemSelected += (sender, e) => {
    ((ListView)sender).SelectedItem = null;

With selection enabled:

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");

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;

Pull-to-Refresh as the user is pulling:

Pull-to-Refresh as the user has released the pull. This is what the user sees while you're updating list:

ListView exposes a few events that allow you to respond to pull-to-refresh events.

  • The RefreshCommand will be invoked and the Refreshing event called. IsRefreshing will be set to true.
  • You should perform whatever code is required to refresh the contents of the list view, either in the command or event.
  • When refreshing is complete, call EndRefresh or set IsRefreshing to false to tell the list view that you're done.

The CanExecute property is respected, which gives you a way to control whether the pull-to-refresh command should be enabled.