How to show context menu for items in .NET MAUI ListView (SfListView)?
The .NET MAUI ListView (SfListView) allows displaying a .NET MAUI Popup (SfPopup) as context menu with different menu items to an item when it is long pressed by customizing the ListView and by using custom view in it. Display the pop-up menu by accessing the touch position in the item based on Position property from ItemLongPress event.
The following code example illustrates that SfListView displays a context menu, adding different menu items and layout the pop-up menu in it.
Defining ListView:
<ContentPage xmlns:syncfusion="clr-namespace:Syncfusion.Maui.ListView;assembly=Syncfusion.Maui.ListView">
<ContentPage.BindingContext>
<local:ContactsViewModel x:Name="viewModel"/>
</ContentPage.BindingContext>
<ContentPage.Content>
<Grid >
<syncfusion:SfListView x:Name="listView" ItemsSource="{Binding contactsinfo}">
<syncfusion:SfListView.Behaviors>
<local:Behavior/>
</syncfusion:SfListView.Behaviors>
<syncfusion:SfListView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Grid VerticalOptions="Center">
<Image Source="{Binding ContactImage}" Grid.Column="0"/>
<StackLayout Grid.Column="1">
<Label Text="{Binding ContactName}"/>
<Label Text="{Binding ContactNumber}"/>
</StackLayout>
</Grid>
<StackLayout HeightRequest="1" BackgroundColor="Gray"/>
</StackLayout>
</DataTemplate>
</syncfusion:SfListView.ItemTemplate>
</syncfusion:SfListView>
</Grid>
</ContentPage.Content>
</ContentPage>
Defining Popup with Sort , Delete and Cancel option:
public class Behavior : Behavior<SfListView>
{
SfListView ListView;
int sortorder = 0;
Contacts item;
View itemView;
SfPopup popupLayout;
protected override void OnAttachedTo(SfListView listView)
{
ListView = listView;
ListView.ItemLongPress += ListView_ItemLongPress;
ListView.ScrollStateChanged += ListView_ScrollStateChanged;
ListView.ItemTapped += ListView_ItemTapped;
base.OnAttachedTo(listView);
}
private void ListView_ItemTapped(object sender, ItemTappedEventArgs e)
{
if (popupLayout != null)
{
popupLayout.Dismiss();
}
}
private void ListView_ScrollStateChanged(object sender, ScrollStateChangedEventArgs e)
{
if (popupLayout != null)
{
popupLayout.Dismiss();
}
}
private void ListView_ItemLongPress(object sender, ItemLongPressEventArgs e)
{
item = e.DataItem as Contacts;
var Layout = ListView.ItemsLayout as LinearLayout;
var rowItems = Layout!.GetType().GetRuntimeFields().First(p => p.Name == "items").GetValue(Layout) as IList;
foreach (ListViewItemInfo iteminfo in rowItems)
{
if(iteminfo.Element != null && iteminfo.DataItem == item)
{
itemView = iteminfo.Element as View;
break;
}
}
popupLayout = new SfPopup();
popupLayout.HeightRequest = 150;
popupLayout.WidthRequest = 100;
popupLayout.ContentTemplate = new DataTemplate(() =>
{
var mainStack = new StackLayout();
mainStack.BackgroundColor = Colors.Teal;
var deletedButton = new Button()
{
Text = "Delete",
HeightRequest=50,
BorderWidth=1,
BorderColor = Colors.White,
BackgroundColor=Colors.Teal,
TextColor = Colors.White
};
deletedButton.Clicked += DeletedButton_Clicked;
var Sortbutton = new Button()
{
Text = "Sort",
BorderWidth = 1,
HeightRequest = 50,
BorderColor = Colors.White,
BackgroundColor = Colors.Teal,
TextColor = Colors.White,
};
Sortbutton.Clicked += Sortbutton_Clicked;
var Dismiss = new Button()
{
Text = "Cancel",
HeightRequest = 50,
BorderWidth = 1,
BorderColor = Colors.White,
BackgroundColor = Colors.Teal,
TextColor = Colors.White,
};
Dismiss.Clicked += Dismiss_Clicked;
mainStack.Children.Add(deletedButton);
mainStack.Children.Add(Sortbutton);
mainStack.Children.Add(Dismiss);
return mainStack;
});
popupLayout.PopupStyle.CornerRadius = 5;
popupLayout.ShowHeader = false;
popupLayout.ShowFooter = false;
popupLayout.ShowRelativeToView(itemView, PopupRelativePosition.AlignBottomRight);
}
private void Dismiss_Clicked(object? sender, EventArgs e)
{
popupLayout.Dismiss();
}
private void Sortbutton_Clicked(object? sender, EventArgs e)
{
if (ListView == null)
return;
ListView.DataSource.SortDescriptors.Clear();
popupLayout.Dismiss();
ListView.DataSource.LiveDataUpdateMode = LiveDataUpdateMode.AllowDataShaping;
if (sortorder == 0)
{
ListView.DataSource.SortDescriptors.Add(new SortDescriptor { PropertyName = "ContactName", Direction = ListSortDirection.Descending });
sortorder = 1;
}
else
{
ListView.DataSource.SortDescriptors.Add(new SortDescriptor { PropertyName = "ContactName", Direction = ListSortDirection.Ascending });
sortorder = 0;
}
}
private void DeletedButton_Clicked(object sender, EventArgs e)
{
if (ListView == null)
return;
var source = ListView.ItemsSource as IList;
if (source != null && source.Contains(item))
{
source.Remove(item);
App.Current.MainPage.DisplayAlert("Alert", item.ContactName + " is deleted", "OK");
}
else
App.Current.MainPage.DisplayAlert("Alert", "Unable to delete the item", "OK");
item = null;
source = null;
}
}
It’s essential to note that due to the limitations of obtaining the touch position accurately about the selected item during the LongPress event, we have strategically positioned the popup at the bottom right of the screen. This ensures a consistent and visually appealing user experience.
Conclusion:
I hope you enjoyed learning about how to add context menu for items in .NET MAUI SfListView.
You can refer to our .NET MAUI SfListView feature tour page to know about its other groundbreaking feature representations and documentation, and how to quickly get started for configuration specifications.
For current customers, you can check out our components from the License and Downloads page. If you are new to Syncfusion, you can try our 30-day free trial to check out our other controls.
If you have any queries or require clarifications, please let us know in the comments section below. You can also contact us through our support forums, Direct-Trac, or feedback portal. We are always happy to assist you!