New to Telerik UI for .NET MAUI? Start a free 30-day trial

.NET MAUI CollectionView Swiping Commands

The .NET MAUI CollectionView provides the following commands related to swipe actions:

  • SwipeStartingCommand(ICommand)—Occurs when an item is about to be swiped. The command parameter is of the CollectionViewSwipeStartingCommandContext type that provides the following properties:
    • Item(object)—The item that will be swiped.
    • Cancel(bool)—If you set this value to false, the swiping will be canceled.
  • Swiping(ICommand)—Occurs while the user is swiping the item. The command parameter is of the CollectionViewSwipingCommandContext type that provides the following properties:
    • Item(object)—The item that is being swiped.
    • Offset(double)—The offset of the swiped item from its initial position.
  • ItemSwipeCompleted(ICommand)—Occurs when the swiping of an item is completed. The command parameter is of the CollectionViewSwipeCompletedCommandContext type that provides the following properties:
    • Item(object)—The item that was swiped.
    • Offset(double)—The final offset of the swiped item.

Check a simple example where the swiping commands are used:

1. Add a CollectionView definition with the swiping commands defined:

<Grid RowDefinitions="Auto, *"
      RowSpacing="16">
    <Grid ColumnDefinitions="Auto, *"
          ColumnSpacing="4"
          Padding="16, 0">
        <Label Text="Log: "
               Style="{StaticResource LogLabelStyle}" />
        <Label Text="{Binding SwipeActionLog}"
               Grid.Column="1"
               Style="{StaticResource LogLabelStyle}" />
    </Grid>
    <telerik:RadCollectionView x:Name="collectionView"
                               Grid.Row="1"
                               ItemsSource="{Binding Locations}"
                               IsItemSwipeEnabled="True"
                               EndItemSwipeCommand="{Binding EndItemSwipeCommand}"
                               StartSwipeTemplate="{StaticResource StartSwipeItemTemplate}"
                               EndSwipeTemplate="{StaticResource EndSwipeItemTemplate}"
                               SwipeStartingCommand="{Binding SwipeStartingCommand}"
                               SwipingCommand="{Binding SwipingCommand}"
                               SwipeCompletedCommand="{Binding SwipeCompletedCommand}"
                               StartSwipeLength="50"
                               EndSwipeLength="50"
                               SwipeThreshold="25">
        <telerik:RadCollectionView.ItemTemplate>
            <DataTemplate>
                <HorizontalStackLayout Spacing="4"
                                       Padding="16, 8">
                    <Label Text="{Binding City}"
                           VerticalTextAlignment="Center" />
                    <Label FontFamily="TelerikFontExamples"
                           FontSize="12"
                           Text="{Binding Visited, Converter={StaticResource VisitedToIconConverter}}"
                           TextColor="#D67F3C"
                           VerticalTextAlignment="Center" />
                </HorizontalStackLayout>
            </DataTemplate>
        </telerik:RadCollectionView.ItemTemplate>
    </telerik:RadCollectionView>
</Grid>

2. Add sample StartSwipeTemplate and EndSwipeTemplate DataTemplates to the page's resources:

<telerik:BoolToValueConverter x:Key="VisitedToIconConverter" TrueValue="&#xe801;" FalseValue="" />
<DataTemplate x:Key="StartSwipeItemTemplate">
    <Grid BackgroundColor="#00897B"
          Padding="12, 0"
          HorizontalOptions="Fill"
          VerticalOptions="Fill">
        <telerik:RadPath Geometry="{x:Static telerik:RadGeometry.Star}"
                         Fill="White"
                         StrokeThickness="0"
                         WidthRequest="16"
                         HeightRequest="16"
                         HorizontalOptions="Center"
                         VerticalOptions="Center" />
    </Grid>
</DataTemplate>
<DataTemplate x:Key="EndSwipeItemTemplate">
    <Grid BackgroundColor="#89000E"
          HorizontalOptions="Fill"
          VerticalOptions="Fill"
          Padding="12, 0">
        <Label FontFamily="{x:Static telerik:TelerikFont.Name}"
               FontSize="16"
               Text="{x:Static telerik:TelerikFont.IconDelete}"
               TextColor="White"
               HorizontalTextAlignment="Center"
               VerticalTextAlignment="Center" />
    </Grid>
</DataTemplate>

3. Add a sample ViewModel class with the commands:

public class ViewModel : NotifyPropertyChangedBase
{
    private string swipeActionLog;

    public ViewModel()
    {
        this.Locations = new ObservableCollection<DataModel>
        {
            new DataModel { Country = "Austria", City = "Vienna", Visited = true },
            new DataModel { Country = "Belgium", City = "Antwerp" },
            new DataModel { Country = "Denmark", City = "Copenhagen" },
            new DataModel { Country = "France", City = "Nice" },
            new DataModel { Country = "France", City = "Paris", Visited = true },
            new DataModel { Country = "Germany", City = "Berlin", Visited = true },
            new DataModel { Country = "Germany", City = "Munich" },
            new DataModel { Country = "Germany", City = "Nuremberg", Visited = true },
            new DataModel { Country = "Italy", City = "Bari" },
            new DataModel { Country = "Italy", City = "Rome" },
            new DataModel { Country = "Netherlands", City = "Amsterdam" },
            new DataModel { Country = "Portugal", City = "Lisbon" },
            new DataModel { Country = "Spain", City = "Barcelona" },
            new DataModel { Country = "Spain", City = "Madrid" },
            new DataModel { Country = "United Kingdom", City = "London" },
            new DataModel { Country = "United Kingdom", City = "Manchester" },
            new DataModel { Country = "United States", City = "New York" },
            new DataModel { Country = "United States", City = "Los Angeles" },
            new DataModel { Country = "United States", City = "Chicago" },
            new DataModel { Country = "United States", City = "Boston" },
            new DataModel { Country = "United States", City = "San Francisco" },
            new DataModel { Country = "Canada", City = "Vancouver" },
            new DataModel { Country = "Brazil", City = "Rio de Janeiro" },
            new DataModel { Country = "Brazil", City = "Sao Paulo" },
            new DataModel { Country = "Argentina", City = "Buenos Aires" },
            new DataModel { Country = "Peru", City = "Lima", Visited = true },
            new DataModel { Country = "Colombia", City = "Bogota" },
            new DataModel { Country = "Bolivia", City = "La Paz" },
            new DataModel { Country = "Venezuela", City = "Caracas" },
            new DataModel { Country = "Chile", City = "Santiago" },
            new DataModel { Country = "China", City = "Hong Kong" },
            new DataModel { Country = "China", City = "Shanghai" },
            new DataModel { Country = "India", City = "Delhi" },
            new DataModel { Country = "Japan", City = "Tokyo", Visited = true },
            new DataModel { Country = "Japan", City = "Osaka" },
            new DataModel { Country = "Vietnam", City = "Hanoi" },
            new DataModel { Country = "Thailand", City = "Bangkok" },
            new DataModel { Country = "Thailand", City = "Phuket" },
            new DataModel { Country = "Nigeria", City = "Lagos" },
            new DataModel { Country = "Egypt", City = "Cairo" },
            new DataModel { Country = "Algeria", City = "Algiers" },
            new DataModel { Country = "Australia", City = "Sydney", Visited = true },
            new DataModel { Country = "Australia", City = "Melbourne" },
            new DataModel { Country = "New Zealand", City = "Auckland" },
            new DataModel { Country = "New Zealand", City = "Wellington" }
        };

        this.SwipeStartingCommand = new Command(this.OnSwipeStartingCommandExecute);
        this.SwipingCommand = new Command(this.OnSwipingCommandExecute);
        this.SwipeCompletedCommand = new Command(this.OnSwipeCompletedCommandExecute);
    }

    public ObservableCollection<DataModel> Locations { get; set; }

    public ICommand SwipeStartingCommand { get; set; }
    public ICommand SwipingCommand { get; set; }
    public ICommand SwipeCompletedCommand { get; set; }
    public ICommand EndItemSwipeCommand { get; set; }

    public string SwipeActionLog
    {
        get => this.swipeActionLog;
        set => UpdateValue(ref this.swipeActionLog, value);
    }

    private void OnSwipeStartingCommandExecute(object obj)
    {
        var context = obj as CollectionViewSwipeStartingCommandContext;
        if (context != null)
        {
            var item = (DataModel)context.Item;
            if (item.Country == "Spain")
            {
                context.Cancel = true;
                this.SwipeActionLog = $"Swiping cities in {item.Country} is canceled";
            }
        }
    }

    private void OnSwipingCommandExecute(object obj)
    {
        var context = obj as CollectionViewSwipingCommandContext;
        if (context != null)
        {
            var item = (DataModel)context.Item;
            this.SwipeActionLog = $"Swiping {item.City} with Offset: {context.Offset:F0}";
        }
    }

    private async void OnSwipeCompletedCommandExecute(object obj)
    {
        var context = obj as CollectionViewSwipeCompletedCommandContext;
        if (context != null)
        {
            var item = (DataModel)context.Item;
            this.SwipeActionLog = $"SwipeCompleted {item.City}";

            if (context.Offset <= -25)
            {
                await Task.Delay(200);
                this.Locations.Remove(item);

                this.SwipeActionLog += $", deleted {item.City}";
                this.EndItemSwipeCommand?.Execute(false);
            }
            else if (context.Offset >= 25)
            {
                await Task.Delay(200);
                item.Visited = !item.Visited;

                this.SwipeActionLog += $", updated {item.City}";
                this.EndItemSwipeCommand?.Execute(true);
            }
        }
    }
}

5. Add a sample DataModel class:

public class DataModel : NotifyPropertyChangedBase
{
    private string country;
    private string city;
    private bool visited;

    public string Country
    {
        get => this.country;
        set => this.UpdateValue(ref this.country, value);
    }

    public string City
    {
        get => this.city;
        set => this.UpdateValue(ref this.city, value);
    }

    public bool Visited
    {
        get => this.visited;
        set => this.UpdateValue(ref this.visited, value);
    }
}

See Also

In this article