- Swipe template
- Swipe events
- Loading multiple views as swipe template
- Customized swipe delete functionality
- Loading complex template for swiping
- Cancel the swipe programmatically
- Set MaxSwipeOffset based on content size
- Load custom swipe buttons based on row data
- Enable swiping for summary and unbound rows
Contact Support
Swiping in MAUI DataGrid (SfDataGrid)
The SfDataGrid enables the swiping option by setting the SfDataGrid.AllowSwiping property to true
. Swipe views are displayed when swiping from left to right
or right to left
on a data row. The control provides customizable swipe templates for both the left and right sides. Additionally, the swipe gesture can be restricted to a certain point on the row by setting the SfDataGrid.MaxSwipeOffset property.
Swipe template
The data grid allows for loading desired content using the SfDataGrid.LeftSwipeTemplate when swiping to the right. The template can be defined either in code or XAML. The content within the swipe template is arranged according to the offset values when swiping a data row.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DataGridMaui.MainPage"
xmlns:local="clr-namespace:DataGridMaui"
xmlns:syncfusion="clr-namespace:Syncfusion.Maui.DataGrid;assembly=Syncfusion.Maui.DataGrid">
<ContentPage.BindingContext>
<local:OrderInfoViewModel/>
</ContentPage.BindingContext>
<ContentPage.Content>
<syncfusion:SfDataGrid x:Name="dataGrid"
ItemsSource="{Binding OrdersInfo}"
AllowSwiping="True">
<syncfusion:SfDataGrid.LeftSwipeTemplate>
<DataTemplate>
<Grid BackgroundColor="#6750A4"
Padding="0" ColumnDefinitions="*, *">
<Label Grid.Column="0"
Text="EDIT"
HorizontalTextAlignment="End"
TextColor="#FFFFFF"
VerticalTextAlignment="Center"
LineBreakMode="NoWrap"
BackgroundColor="Transparent"/>
<Image Grid.Column="1"
Source="edit.png"
HeightRequest="18"
WidthRequest="18"
Margin="12,0,0,0"
HorizontalOptions="Start"
VerticalOptions="Center"/>
</Grid>
</DataTemplate>
</syncfusion:SfDataGrid.LeftSwipeTemplate>
</syncfusion:SfDataGrid>
</ContentPage.Content>
</ContentPage>
public partial class MainPage : ContentPage
{
SfDataGrid dataGrid;
OrderInfoViewModel viewModel;
public MainPage()
{
InitializeComponent();
dataGrid = new SfDataGrid();
viewModel = new OrderInfoViewModel();
dataGrid.ItemsSource = viewModel.OrdersInfo;
dataGrid.AllowSwiping = true;
dataGrid.LeftSwipeTemplate = new DataTemplate(() =>
{
var grid = new Grid
{
BackgroundColor = Color.FromArgb("#6750A4"),
Padding = new Thickness(0)
};
grid.ColumnDefinitions.Add(new ColumnDefinition());
grid.ColumnDefinitions.Add(new ColumnDefinition());
var editLabel = new Label
{
Text = "EDIT",
HorizontalTextAlignment = TextAlignment.End,
TextColor = Colors.White,
VerticalTextAlignment = TextAlignment.Center,
LineBreakMode = LineBreakMode.NoWrap,
BackgroundColor = Colors.Transparent
};
Grid.SetColumn(editLabel, 0);
var image = new Image
{
Source="edit.png",
HeightRequest = 18,
WidthRequest = 18,
Margin = new Thickness(12, 0, 0, 0),
HorizontalOptions = LayoutOptions.Start,
VerticalOptions = LayoutOptions.Center
};
Grid.SetColumn(image, 1);
grid.Children.Add(editLabel);
grid.Children.Add(image);
return grid;
});
Content = dataGrid;
}
}
NOTE
Similarly, the desired content can be loaded using the SfDataGrid.RightSwipeTemplate when swiping to the left.
NOTE
The
DataTemplateSelector
can be directly assigned to both theSfDataGrid.RightSwipeTemplate
and theSfDataGrid.LeftSwipeTemplate
. You can load the appropriate template based on the RowData and the row element provided in the event arguments.
Swipe events
SwipeStarting: Raised when the swipe offset changes from its initial value. The swipe action can be canceled by setting the Cancel
property of the DataGridSwipeStartingEventArgs to true
.
SwipeEnded: The event is triggered when the swipe offset value reaches SfDataGrid.MaxSwipeOffset
, indicating that the swipe action is complete. This event is triggered with DataGridSwipeEndedEventArgs.
Swiping
: The event is raised while a row is being swiped. This event is triggered with DataGridSwipingEventArgs.
The swipe events provide the following properties in their arguments:
- RowIndex: Defines the index of the swiping row.
- RowData: Defines the underlying data associated with the swiped row as its argument.
- SwipeDirection: Defines the swipe direction of the swiped row.
- SwipeOffset: Defines the current swipe offset of the row that is being swiped.
By handling the swipe events, you can use the values of these properties from the arguments to perform any desired actions, such as deleting a row or editing the data, etc.
Loading multiple views as swipe template
The swipe templates can be customized by loading any view into the templates and assigning custom actions to them, such as deleting a row, adding a row, or editing the underlying associated data. Multiple views can also be displayed in a template, as shown in the following example, where two views are loaded for editing the cell values in a row and deleting the row, respectively.
<ContentPage.Content>
<syncfusion:SfDataGrid x:Name="dataGrid"
ItemsSource="{Binding OrdersInfo}"
AllowSwiping="True"
AutoGenerateColumnsMode="None"
SwipeEnded="dataGrid_SwipeEnded">
<syncfusion:SfDataGrid.LeftSwipeTemplate>
<DataTemplate>
<Grid ColumnDefinitions="*,*">
<Grid.GestureRecognizers>
<TapGestureRecognizer NumberOfTapsRequired="1"
Tapped="TapGestureRecognizer_InsertButtonTapped" />
</Grid.GestureRecognizers>
<Grid BackgroundColor="#009EDA" ColumnDefinitions="4*,6*" Grid.Column="0">
<Image Grid.Column="0"
HorizontalOptions="End"
Source="insert.png"
HeightRequest="18"
WidthRequest="18"
Margin="0,0,8,0"/>
<Label Grid.Column="1"
BackgroundColor="Transparent"
LineBreakMode="NoWrap"
Text="INSERT"
TextColor="White"
HorizontalTextAlignment ="Start"
VerticalTextAlignment="Center" />
</Grid>
<Grid Grid.Column="1" BackgroundColor="#DC595F" ColumnDefinitions="4*,6*">
<Grid.GestureRecognizers>
<TapGestureRecognizer NumberOfTapsRequired="1"
Tapped="TapGestureRecognizer_DeleteButtonTapped" />
</Grid.GestureRecognizers>
<Image Grid.Column="0"
BackgroundColor="Transparent"
HorizontalOptions="CenterAndExpand"
Source="delete.png"
HeightRequest="18"
WidthRequest="18"/>
<Label Grid.Column="1"
BackgroundColor="Transparent"
LineBreakMode="NoWrap"
Text="DELETE"
TextColor="White"
HorizontalOptions="Start"
HorizontalTextAlignment ="Start"
VerticalTextAlignment ="Center" />
</Grid>
</Grid>
</DataTemplate>
</syncfusion:SfDataGrid.LeftSwipeTemplate>
</syncfusion:SfDataGrid>
</ContentPage.Content>
public partial class MainPage : ContentPage
{
private int swipedRowIndex;
public MainPage()
{
InitializeComponent();
}
private void TapGestureRecognizer_InsertButtonTapped(object sender, TappedEventArgs e)
{
InsertButtonPressed();
}
private void TapGestureRecognizer_DeleteButtonTapped(object sender, TappedEventArgs e)
{
DeleteButtonPressed();
}
internal void DeleteButtonPressed()
{
viewModel.OrdersInfo.RemoveAt(swipedRowIndex - 1);
}
internal void InsertButtonPressed()
{
viewModel.OrdersInfo.Insert(this.swipedRowIndex - 1, InsertItems());
}
private void dataGrid_SwipeEnded(object sender, Syncfusion.Maui.DataGrid.DataGridSwipeEndedEventArgs e)
{
this.swipedRowIndex = e.RowIndex;
}
internal OrderInfo InsertItems()
{
var ordeshipcity = "Italy";
var order = new OrderInfo()
{
OrderID = 1101,
CustomerID = "Frans",
ShipCity = "Italy",
ShipCountry = "France",
};
return order;
}
}
NOTE
Similarly, you can load two views using the
SfDataGrid.RightSwipeTemplate
when swiping towards left will result in the following outcome:
Customized swipe delete functionality
Operations such as deleting a row by swiping a data row from one extent to another in the view can be performed.
<syncfusion:SfDataGrid x:Name="dataGrid"
ItemsSource="{Binding OrdersInfo}"
AllowSwiping="True"
MaxSwipeOffset="404"
SwipeEnded="dataGrid_SwipeEnded">
<syncfusion:SfDataGrid.LeftSwipeTemplate>
<DataTemplate>
<ContentView x:Name="leftTemplateView"
BackgroundColor="#1AAA87">
<Label FontSize="15"
Text ="Deleted"
TextColor ="White"
HorizontalTextAlignment ="Center"
VerticalTextAlignment ="Center"/>
</ContentView>
</DataTemplate>
</syncfusion:SfDataGrid.LeftSwipeTemplate>
<syncfusion:SfDataGrid.RightSwipeTemplate>
<DataTemplate>
<ContentView x:Name="rightTemplateView"
BackgroundColor="#1AAA87">
<Label FontSize="15"
HorizontalTextAlignment ="Center"
Text ="Deleted"
TextColor ="White"
VerticalTextAlignment ="Center" />
</ContentView>
</DataTemplate>
</syncfusion:SfDataGrid.RightSwipeTemplate>
</syncfusion:SfDataGrid>
public partial class MainPage : ContentPage
{
private int swipedRowIndex;
public MainPage()
{
InitializeComponent();
}
private void dataGrid_SwipeEnded(object sender, Syncfusion.Maui.DataGrid.DataGridSwipeEndedEventArgs e)
{
swipedRowIndex = e.RowIndex;
doDeleting();
}
private void doDeleting()
{
viewModel.OrdersInfo.RemoveAt(swipedRowIndex - 1);
}
}
Loading complex template for swiping
The datagrid allows you to swipe the data rows, even when we have a complex template in DataGridTemplateColumn
.
<syncfusion:SfDataGrid x:Name="dataGrid"
ItemsSource="{Binding OrdersInfo}"
AllowSwiping="True"
MaxSwipeOffset="180"
RowHeight="60">
<syncfusion:SfDataGrid.LeftSwipeTemplate>
<DataTemplate>
<Grid BackgroundColor="#6750A4" Padding="0" ColumnDefinitions="*,*">
<Label Grid.Column="0"
Text="EDIT"
HorizontalTextAlignment="End"
TextColor="#FFFFFF"
VerticalTextAlignment="Center"
LineBreakMode="NoWrap"
BackgroundColor="Transparent"/>
<Image Grid.Column="1"
Source="edit.png"
HeightRequest="18"
WidthRequest="18"
Margin="12,0,0,0"
HorizontalOptions="Start"
VerticalOptions="Center"/>
</Grid>
</DataTemplate>
</syncfusion:SfDataGrid.LeftSwipeTemplate>
<syncfusion:SfDataGrid.Columns>
<syncfusion:DataGridTemplateColumn MappingName="CustomerID" HeaderText="Customer Details" Width="140">
<syncfusion:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid InputTransparent="True"
ColumnSpacing="0"
RowSpacing="0"
HorizontalOptions="FillAndExpand"
Margin="0"
ColumnDefinitions="*,*,*"
RowDefinitions="10,*,10">
<StackLayout
Margin="2"
BackgroundColor="White"
Orientation="Vertical"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
Grid.Column="0"
Grid.ColumnSpan="3"
Grid.Row="1">
<StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand" >
<Label Text="Customer ID: " HorizontalTextAlignment="Start" FontSize="13" Padding="0,0,4,0"/>
<Label Text="{Binding CustomerID}" FontAttributes="Bold" TextColor="Black" FontSize="13" HorizontalTextAlignment="Start"/>
</StackLayout>
<StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand">
<Label Text="Country:" HorizontalTextAlignment="Start" FontSize="13" Padding="0,0,4,0"/>
<Label Text="{Binding ShipCountry}" FontAttributes="Bold" TextColor="Black" FontSize="13" HorizontalTextAlignment="Start"/>
</StackLayout>
</StackLayout>
</Grid>
</DataTemplate>
</syncfusion:DataGridTemplateColumn.CellTemplate>
</syncfusion:DataGridTemplateColumn>
</syncfusion:SfDataGrid.Columns>
</syncfusion:SfDataGrid>
Cancel the swipe programmatically
The data grid allows you to cancel the swipe programmatically by calling the SfDataGrid.ResetSwipeOffset() method in the SfDataGrid.SwipeEnded event.
<syncfusion:SfDataGrid x:Name="dataGrid"
ItemsSource="{Binding OrdersInfo}"
AllowSwiping="True"
SwipeEnded="dataGrid_SwipeEnded">
<syncfusion:SfDataGrid.LeftSwipeTemplate>
<DataTemplate>
<Grid BackgroundColor="Blue" Padding="9">
<Label Text ="Edit"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center"
LineBreakMode ="NoWrap"
BackgroundColor="Transparent"
TextColor ="White" />
</Grid>
</DataTemplate>
</syncfusion:SfDataGrid.LeftSwipeTemplate>
<syncfusion:SfDataGrid.RightSwipeTemplate>
<DataTemplate>
<Grid BackgroundColor="Red" Padding="9">
<Label FontSize="15"
HorizontalTextAlignment ="Center"
Text ="Delete"
TextColor ="White"
VerticalTextAlignment ="Center"
LineBreakMode ="NoWrap" />
</Grid>
</DataTemplate>
</syncfusion:SfDataGrid.RightSwipeTemplate>
</syncfusion:SfDataGrid>
private void dataGrid_SwipeEnded(object sender, Syncfusion.Maui.DataGrid.DataGridSwipeEndedEventArgs e)
{
dataGrid.ResetSwipeOffset();
}
Set MaxSwipeOffset based on content size
Users can restrict the max swipe offset of a row to the width of the content loaded inside the swipe template by setting the SfDataGrid.SwipeOffsetMode as SwipeOffsetMode.Auto. The default value of the SwipeOffsetMode
is SwipeOffsetMode.Custom.
<syncfusion:SfDataGrid x:Name="datagrid"
AllowSwiping="True"
SwipeOffsetMode="Auto"
ItemsSource="{Binding OrdersInfo}"
</syncfusion:SfDataGrid>
dataGrid.SwipeOffsetMode=SwipeOffsetMode.Auto;
NOTE
The value of the
SfDataGrid.MaxSwipeOffset
property will not be considered when theSfDataGrid.SwipeOffsetMode
is set toSwipeOffsetMode.Auto
.
Load custom swipe buttons based on row data
Using a DataTemplateSelector
, you can load specific views based on row data, such as SfDataGrid.RightSwipeTemplate
and SfDataGrid.LeftSwipeTemplate
. Refer to the code example below to load the desired template based on the row data.
<syncfusion:SfDataGrid x:Name="dataGrid"
ItemsSource="{Binding OrdersInfo}"
AllowSwiping="True">
<syncfusion:SfDataGrid.LeftSwipeTemplate>
<local:LeftTemplateSelector/>
</syncfusion:SfDataGrid.LeftSwipeTemplate>
<syncfusion:SfDataGrid.RightSwipeTemplate>
<local:RightTemplateSelector/>
</syncfusion:SfDataGrid.RightSwipeTemplate>
</syncfusion:SfDataGrid>
public class LeftTemplateSelector : DataTemplateSelector
{
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
var value = (item as OrderInfo).IsClosed;
if (value)
{
var dataTemplate = new DataTemplate(() =>
{
Button button = new Button()
{
TextColor = Colors.Green,
VerticalOptions = LayoutOptions.Center,
HorizontalOptions = LayoutOptions.Center,
Text = "Online",
BackgroundColor = Colors.LightGray,
WidthRequest = 200,
CornerRadius = 0,
FontAttributes = FontAttributes.Bold
};
return button;
});
return dataTemplate;
}
else
{
var dataTemplate = new DataTemplate(() =>
{
Button button = new Button()
{
TextColor = Colors.Red,
VerticalOptions = LayoutOptions.Center,
HorizontalOptions = LayoutOptions.Center,
Text = "Offline",
WidthRequest = 200,
BackgroundColor = Colors.LightGray,
CornerRadius = 0,
FontAttributes = FontAttributes.Bold
};
return button;
});
return dataTemplate;
}
}
}
public class RightTemplateSelector : DataTemplateSelector
{
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
var value = (item as OrderInfo).IsClosed;
if (value)
{
var dataTemplate = new DataTemplate(() =>
{
Button button = new Button()
{
TextColor = Colors.Green,
VerticalOptions = LayoutOptions.Center,
HorizontalOptions = LayoutOptions.Center,
Text = "Online",
BackgroundColor = Colors.LightGray,
WidthRequest = 200,
CornerRadius = 0,
FontAttributes = FontAttributes.Bold
};
return button;
});
return dataTemplate;
}
else
{
var dataTemplate = new DataTemplate(() =>
{
Button button = new Button()
{
TextColor = Colors.Red,
VerticalOptions = LayoutOptions.Center,
HorizontalOptions = LayoutOptions.Center,
Text = "Offline",
BackgroundColor = Colors.LightGray,
WidthRequest = 200,
CornerRadius = 0,
FontAttributes = FontAttributes.Bold
};
return button;
});
return dataTemplate;
}
}
}
The following screenshot illustrates the custom swipe buttons that are loaded based on the cell value of the “Is Online” switch column.
Enable swiping for summary and unbound rows
To enable swiping of the UnboundRow
, CaptionSummaryRow
, GroupSummaryRow
, and TableSummaryRow
, set the Cancel
property of the SwipeStartedEventArgs
to false in the SfDataGrid.SwipeStarted
event handler. By default, the Cancel
property is set to true for all non-data rows.
private void dataGrid_SwipeStarting(object sender, Syncfusion.Maui.DataGrid.DataGridSwipeStartingEventArgs e)
{
if(dataGrid.IsUnboundRow(e.RowIndex) || dataGrid.IsCaptionSummaryRow(e.RowIndex) || dataGrid.IsGroupSummaryRow(e.RowIndex))
{
e.Cancel = false;
}
else if (e.RowData.GetType() == typeof(SummaryRecordEntry))
{
if ((e.RowData as SummaryRecordEntry).Parent?.GetType() == typeof(Group))
{
//// Enable swiping for group summary row.
e.Cancel = false;
}
else
{
//// Enable swiping for table summary row.
e.Cancel = false;
}
}
}