.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 theCollectionViewSwipeStartingCommandContext
type that provides the following properties:-
Item
(object
)—The item that will be swiped. -
Cancel
(bool
)—If you set this value tofalse
, the swiping will be canceled.
-
-
Swiping
(ICommand
)—Occurs while the user is swiping the item. The command parameter is of theCollectionViewSwipingCommandContext
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 theCollectionViewSwipeCompletedCommandContext
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="" 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);
}
}