Skip to content

Learn Mobile Development

Alamgeer's Blog

Menu
  • Home
  • Privacy Policy
Menu
Item Reordering in MAUI

How to use drag and drop gesture to CollectionView in MAUI

Posted on January 14, 2023January 18, 2023 by Learn Mobile Development

MAUI provides us drag and drop gestures which enables drag an element from one place and drop to another place. We can apply drag and drop gestures to any UI elements using DragGestureRecognizer and DropGestureRecognizer class. So In this article, I’m going to show you how to use drag and drop gesture to CollectionView in MAUI.

 Note : To implement drag and drop in iOS platform minimum iOS version 11 required.

Let’s Start

1 – Setting up the UI

1.1 – Create a MainPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
    x:Class="MAUIDragDropCollectionViewItemsDemo.MainPage"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:converter="clr-namespace:MAUIDragDropCollectionViewItemsDemo"
    x:Name="MainPageContainer">

    <ContentPage.Resources>
        <ResourceDictionary>
            <converter:BoolToColorConverter x:Key="BoolToColor" />
        </ResourceDictionary>
    </ContentPage.Resources>

    <Grid
        Padding="30,5"
        HorizontalOptions="Fill"
        RowDefinitions="*,Auto"
        RowSpacing="10"
        VerticalOptions="Fill">

        <CollectionView
            Grid.Row="0"
            Margin="0,30,0,0"
            ItemsSource="{Binding UserList}"
            SelectionMode="None">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <Frame
                        Padding="3"
                        BorderColor="{StaticResource Primary}"
                        CornerRadius="0"
                        IsClippedToBounds="True">
                        <VerticalStackLayout>
                            <StackLayout
                                Padding="10"
                                BackgroundColor="{Binding IsBeingDragged, Converter={StaticResource BoolToColor}}"
                                HeightRequest="60"
                                HorizontalOptions="FillAndExpand"
                                Orientation="Horizontal"
                                VerticalOptions="FillAndExpand">

                                <!--  User Image  -->
                                <Image
                                    HeightRequest="50"
                                    Source="user.png"
                                    WidthRequest="50">
                                    <Image.Clip>
                                        <EllipseGeometry
                                            Center="50,50"
                                            RadiusX="100"
                                            RadiusY="100" />
                                    </Image.Clip>
                                </Image>

                                <!--  User Name  -->
                                <Label
                                    x:Name="UserName"
                                    Margin="10,0,0,0"
                                    HorizontalOptions="FillAndExpand"
                                    Text="{Binding UserName}"
                                    TextColor="Black"
                                    VerticalTextAlignment="Center" />

                                <!--  Delete Icon  -->
                                <Frame
                                    Padding="7"
                                    CornerRadius="15"
                                    HeightRequest="30"
                                    HorizontalOptions="EndAndExpand"
                                    WidthRequest="30">
                                    <Image Source="delete_user.png" />
                                    <Frame.GestureRecognizers>
                                        <TapGestureRecognizer Command="{Binding BindingContext.DeleteUserCommand, Source={x:Reference MainPageContainer}}" CommandParameter="{Binding .}" />
                                    </Frame.GestureRecognizers>
                                </Frame>

                                <StackLayout.GestureRecognizers>
                                    <DragGestureRecognizer
                                        CanDrag="True"
                                        DragStartingCommand="{Binding BindingContext.ItemDraggedCommand, Source={x:Reference MainPageContainer}}"
                                        DragStartingCommandParameter="{Binding}" />
                                    <DropGestureRecognizer
                                        AllowDrop="True"
                                        DragLeaveCommand="{Binding BindingContext.ItemDragLeaveCommand, Source={x:Reference MainPageContainer}}"
                                        DragLeaveCommandParameter="{Binding}"
                                        DragOverCommand="{Binding BindingContext.ItemDraggedOverCommand, Source={x:Reference MainPageContainer}}"
                                        DragOverCommandParameter="{Binding}"
                                        DropCommand="{Binding BindingContext.ItemDroppedCommand, Source={x:Reference MainPageContainer}}"
                                        DropCommandParameter="{Binding}" />
                                </StackLayout.GestureRecognizers>
                            </StackLayout>

                            <StackLayout
                                BackgroundColor="LightGray"
                                HeightRequest="30"
                                HorizontalOptions="FillAndExpand"
                                IsVisible="{Binding IsBeingDraggedOver}"
                                VerticalOptions="FillAndExpand" />
                        </VerticalStackLayout>
                    </Frame>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>

        <VerticalStackLayout Grid.Row="1">

            <Entry Placeholder="Type name" Text="{Binding User}" />

            <Button
                Margin="0,10,0,0"
                Command="{Binding AddUserCommand}"
                HorizontalOptions="CenterAndExpand"
                Text="Add User" />

        </VerticalStackLayout>

    </Grid>

</ContentPage>
  • As in the above MainPage.xaml, I have taken CollectionView to show list of user and Entry/Button to add new user.
  • BoolToColorConverter is used for changing the color based on bool value passed at runtime.
  • And I have also used DragGestureRecognizer and DropGestureRecognizer gestures to collectionview item.
  • DragStartingCommand – It’s a command which gets executed while dragging start.
  • DragStartingCommandParameter – It’s an object type which passed to DragStartingCommand.
  • DragLeaveCommand – It’s also a command which gets executed while an element is dragged out of the control’s bounds.
  • DragLeaveCommandParameter – It’s an object type which passed to DragLeaveCommand.
  • DragOverCommand – It’s also a command which gets executed while an element is dragged over the control’s bounds.
  • DragOverCommandParameter – It’s an object type which passed to DragOverCommand.
  • DropCommand – It’s also a command which gets executed while an element is dropped over the target control.
  • DropCommandParameter – It’s an object type which passed to DropCommand.

1.2 – Create a BoolToColorConverter.cs

using System.Globalization;

namespace MAUIDragDropCollectionViewItemsDemo
{
    public class BoolToColorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var isBeingDragged = (bool?)value;
            var result = (isBeingDragged ?? false) ? Color.FromArgb("#bcacdc") : Color.FromArgb("#FFFFFF");
            return result;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value;
        }
    }
}

2 – Setting up the ViewModel

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System.Collections.ObjectModel;
using System.Diagnostics;

namespace MAUIDragDropCollectionViewItemsDemo
{
    public partial class MainPageViewModel : ObservableObject
    {
        [ObservableProperty]
        private ObservableCollection<User> userList;

        [ObservableProperty]
        private string user;

        private User _itemBeingDragged;

        public MainPageViewModel()
        {
            GetUserList();
        }

        [RelayCommand]
        public void AddUser()
        {
            Application.Current.Dispatcher.Dispatch(() =>
            {
                if (!string.IsNullOrEmpty(User))
                {
                    UserList.Add(new User() { UserName = User });
                    User = string.Empty;
                }
            });
        }

        [RelayCommand]
        public void DeleteUser(User user)
        {
            Application.Current.Dispatcher.Dispatch(() =>
            {
                if (UserList.Contains(user))
                {
                    UserList.Remove(user);
                }
            });
        }

        [RelayCommand]
        public void ItemDragged(User user)
        {
            Debug.WriteLine($"ItemDragged : {user?.UserName}");

            user.IsBeingDragged = true;
            _itemBeingDragged = user;
        }

        [RelayCommand]
        public void ItemDragLeave(User user)
        {
            Debug.WriteLine($"ItemDragLeave : {user?.UserName}");

            user.IsBeingDraggedOver = false;
        }

        [RelayCommand]
        public void ItemDraggedOver(User user)
        {
            Debug.WriteLine($"ItemDraggedOver : {user?.UserName}");

            if (user == _itemBeingDragged)
            {
                user.IsBeingDragged = false;
            }
            user.IsBeingDraggedOver = user != _itemBeingDragged;
        }

        [RelayCommand]
        public void ItemDropped(User user)
        {
            try
            {
                var itemToMove = _itemBeingDragged;
                var itemToInsertBefore = user;

                if (itemToMove == null || itemToInsertBefore == null || itemToMove == itemToInsertBefore)
                    return;

                int insertAtIndex = UserList.IndexOf(itemToInsertBefore);

                if (insertAtIndex >= 0 && insertAtIndex < UserList.Count)
                {
                    UserList.Remove(itemToMove);
                    UserList.Insert(insertAtIndex, itemToMove);

                    itemToMove.IsBeingDragged = false;
                    itemToInsertBefore.IsBeingDraggedOver = false;
                }

                Debug.WriteLine($"ItemDropped: [{itemToMove?.UserName}] => [{itemToInsertBefore?.UserName}], target index = [{insertAtIndex}]");
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }

        private void GetUserList()
        {
            UserList = new ObservableCollection<User>()
            {
                new User(){UserName = "User 1"},
                new User(){UserName = "User 2"},
                new User(){UserName = "User 3"},
                new User(){UserName = "User 4"},
                new User(){UserName = "User 5"},
                new User(){UserName = "User 6"},
            };
        }
    }

    public partial class User : ObservableObject
    {
        [ObservableProperty]
        private string userName;

        [ObservableProperty]
        private bool isBeingDragged;

        [ObservableProperty]
        private bool isBeingDraggedOver;
    }
}
  • As you will see I have used the ObservableObject class for data binding and I already explained about this in my last article. You can visit this link for more details.

Result

That’s all for now!

You can check the full source code here.

Happy Coding! 😀 

You may also like

Item reordering to CollectionView

How to apply item reordering to CollectionView GridItemsLayout in MAUI

ObservableObject in MAUI

How to use ObservableObject in MAUI for Data Binding

Post Views: 426
Share article with

2 thoughts on “How to use drag and drop gesture to CollectionView in MAUI”

  1. Felipe C says:
    June 6, 2023 at 11:42 PM

    Great and pretty straightforward tutorial, thanks!

    Reply
  2. Luke says:
    September 25, 2024 at 2:04 PM

    Thanks very much!

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

I'm Alamgeer Ashraf and having 11+ years of experience in enterprises mobile application development with Xamarin Native, Xamarin Forms & .Net MAUI.

Archives

  • February 2023 (1)
  • January 2023 (9)
  • December 2022 (5)
  • November 2022 (6)

Latest Posts

  • Prevent Dark Mode in Xamarin forms
    How to Prevent Dark Mode in Xamarin formsFebruary 3, 2023
  • apply color to Images
    How to apply color to Images and Icons in MAUIJanuary 30, 2023
  • iOS Large Page Title
    How to set iOS large page title in MAUIJanuary 26, 2023
  • Change StatusBar Color
    How to change StatusBar color in MAUIJanuary 22, 2023
  • Item reordering to CollectionView
    How to apply item reordering to CollectionView GridItemsLayout in MAUIJanuary 18, 2023

Popular Posts

  • How to use CollectionView as a GridItemLayout in Xamarin Forms
  • How to change StatusBar color in MAUI
  • .Net MAUI – The Latest CarouselView with IndicatorView

Latest Comments

  1. knight online makro on Implementation Of Biometric Authentication in Xamarin FormsFebruary 12, 2026

    Your blog is always a highlight of my day

  2. dịch vụ backlink top.com vn on How to use CollectionView as a GridItemLayout in Xamarin FormsNovember 20, 2025

    Great post, you have pointed out some fantastic details , I besides think this s a very superb website.

  3. ryzen sunucu kirala on Implementation Of Biometric Authentication in Xamarin FormsNovember 4, 2025

    Thank you for sharing your personal experience and wisdom with us Your words are so encouraging and uplifting

  4. dofollow backlinks means on How to use FlexLayout in MAUIOctober 29, 2025

    Perfect piece of work you have done, this site is really cool with superb info .

  5. backlinks que es on How to use ObservableObject in MAUI for Data BindingOctober 28, 2025

    I like this internet site because so much useful stuff on here : D.

Our Visitor

0 0 8 9 6 8
Users Today : 7
Users Yesterday : 1
Users Last 7 days : 55
Users Last 30 days : 129
Users This Month : 38
Total views : 15411
How to use FlexLayout in MAUI
Trending
How to use FlexLayout in MAUI

Category

  • .Net MAUI
  • MAUI Community Toolkit
  • MVVM
  • Xamarin Community Toolkit
  • Xamarin Forms

Contact Me

  • LinkedIn
      © 2026 Learn Mobile Development