Skip to content

Learn Mobile Development

Alamgeer's Blog

Menu
  • Home
  • Privacy Policy
Menu
Item reordering to CollectionView

How to apply item reordering to CollectionView GridItemsLayout in MAUI

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

Drag and Drop gestures enable 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. In my last post I explained how to apply drag and drop gestures to CollectionView LinearItemsLayout click here to see. So In this article, I’m going to show you how to apply Item reordering to CollectionView GridItemsLayout 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="MAUICollectionViewItemReorderingSample.MainPage"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:vm="clr-namespace:MAUICollectionViewItemReorderingSample"
    x:Name="MainPageContainer">

    <ContentPage.BindingContext>
        <vm:MainPageViewModel />
    </ContentPage.BindingContext>

    <ScrollView>
        <VerticalStackLayout
            Padding="5,0"
            Spacing="15"
            VerticalOptions="FillAndExpand">

            <CollectionView
                Margin="2"
                CanReorderItems="True"
                ItemsSource="{Binding ImageList}"
                SelectionMode="None"
                VerticalOptions="FillAndExpand">

                <!--  Item Layout  -->
                <CollectionView.ItemsLayout>
                    <GridItemsLayout Orientation="Vertical" Span="2" />
                </CollectionView.ItemsLayout>

                <!--  Item Template  -->
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <StackLayout
                            BackgroundColor="White"
                            HeightRequest="180"
                            HorizontalOptions="FillAndExpand"
                            IsClippedToBounds="True"
                            Spacing="8"
                            VerticalOptions="FillAndExpand">

                            <Frame
                                x:Name="FrameContainer"
                                Margin="8"
                                Padding="0,0,0,0"
                                BackgroundColor="White"
                                BorderColor="{StaticResource Primary}"
                                CornerRadius="0"
                                HasShadow="True"
                                HorizontalOptions="FillAndExpand"
                                IsClippedToBounds="True"
                                VerticalOptions="FillAndExpand">
                                <StackLayout
                                    HorizontalOptions="FillAndExpand"
                                    IsClippedToBounds="True"
                                    Orientation="Vertical"
                                    Spacing="0"
                                    VerticalOptions="FillAndExpand">

                                    <StackLayout
                                        Margin="{OnPlatform Android='3,3,5,0',
                                                            iOS='0,0,0,0'}"
                                        BackgroundColor="{Binding HeaderColor}"
                                        HeightRequest="60"
                                        HorizontalOptions="Fill" />

                                    <!--  Banner Image  -->
                                    <Frame
                                        Margin="0,-40,0,0"
                                        Padding="0"
                                        BackgroundColor="Transparent"
                                        BorderColor="White"
                                        CornerRadius="50"
                                        HasShadow="True"
                                        HeightRequest="100"
                                        HorizontalOptions="CenterAndExpand"
                                        IsClippedToBounds="True"
                                        VerticalOptions="Start"
                                        WidthRequest="100">
                                        <Image
                                            x:Name="BannerImage"
                                            Aspect="AspectFill"
                                            HeightRequest="99"
                                            IsAnimationPlaying="True"
                                            Source="{Binding ImageUrl}"
                                            WidthRequest="99" />
                                    </Frame>

                                    <StackLayout Margin="0,10,0,0">
                                        <Label
                                            FontSize="16"
                                            HorizontalTextAlignment="Center"
                                            Text="{Binding ImageName}"
                                            TextColor="Black" />
                                    </StackLayout>
                                </StackLayout>
                            </Frame>

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

                        </StackLayout>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
        </VerticalStackLayout>
    </ScrollView>
</ContentPage>
  • As in the above MainPage.xaml, I have taken CollectionView GridItemsLayout to show banners.
  • DragStartingCommand – It’s a command which gets executed while dragging start.
  • DragStartingCommandParameter – It’s an object type which passed to DragStartingCommand. 
  • 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.

2 – Setting up the ViewModel

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

namespace MAUICollectionViewItemReorderingSample
{
    public partial class MainPageViewModel : ObservableObject
    {
        [ObservableProperty]
        ObservableCollection<BannerImage> imageList;

        private BannerImage _itemBeingDragged;

        public MainPageViewModel()
        {
            GetImageList();
        }

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

            _itemBeingDragged = user;
        }

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

            try
            {
                var itemToMove = _itemBeingDragged;
                var itemToInsertBefore = user;

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

                int insertAtIndex = ImageList.IndexOf(itemToInsertBefore);

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

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

        public void GetImageList()
        {
            ImageList = new ObservableCollection<BannerImage>();

            ImageList.Add(new BannerImage()
            {
                HeaderColor = Color.FromArgb("#F7DC6F"),
                ImageName = "Image img6",
                ImageUrl = ImageSource.FromFile("img6.jpg")
            });

            ImageList.Add(new BannerImage()
            {
                HeaderColor = Color.FromArgb("#7DCEA0"),
                ImageName = "Image img7",
                ImageUrl = ImageSource.FromFile("img7.jpg")
            });

            ImageList.Add(new BannerImage()
            {
                HeaderColor = Color.FromArgb("#7FB3D5"),
                ImageName = "Image img8",
                ImageUrl = ImageSource.FromFile("img8.jpeg")
            });

            ImageList.Add(new BannerImage()
            {
                HeaderColor = Color.FromArgb("#00FF00"),
                ImageName = "Pexels 257840",
                ImageUrl = ImageSource.FromFile("gif4.gif")
            });

            ImageList.Add(new BannerImage()
            {
                HeaderColor = Color.FromArgb("#F0048A"),
                ImageName = "Pexels 257840",
                ImageUrl = ImageSource.FromFile("gif5.gif")
            });

            ImageList.Add(new BannerImage()
            {
                HeaderColor = Color.FromArgb("#D7DBDD"),
                ImageName = "Image img5",
                ImageUrl = ImageSource.FromFile("img5.jpeg")
            });

            ImageList.Add(new BannerImage()
            {
                HeaderColor = Color.FromArgb("#C39BD3"),
                ImageName = "Image img9",
                ImageUrl = ImageSource.FromFile("img9.jpeg")
            });
        }
    }

    public partial class BannerImage : ObservableObject
    {
        [ObservableProperty]
        private ImageSource imageUrl;

        [ObservableProperty]
        private string imageName;

        [ObservableProperty]
        private string imageDesc = "Lorem Ipsum is simply dummy text of the printing and typesetting industry.";

        [ObservableProperty]
        private bool isSquareView;

        [ObservableProperty]
        private Color headerColor;
    }
}
  • As you will see I have used the ObservableObject class for data binding and I already explained about this in my previous 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 in MAUI

How to use drag and drop gesture to CollectionView in MAUI

ObservableObject in MAUI

How to use ObservableObject in MAUI for Data Binding

Post Views: 397
Share article with

5 thoughts on “How to apply item reordering to CollectionView GridItemsLayout in MAUI”

  1. Mohammad reza says:
    January 19, 2023 at 5:45 AM

    Thank you very much.

    Reply
  2. Tiago Rosolen says:
    June 24, 2023 at 7:23 PM

    Hi Alamgeer and thank you for the nice example.

    I changes my project to use the ScrollView exactly like you’ve suggested but now my SelectionChangedCommand from my CollectionView never fire.

    I tried to add “” to the GestureRecognizers list. It works but the item must on the ItemViewModel and not on the ListOfItemsViewModel. How can we fire a list selection change event?

    If you could be so kind to give me some light on this, I would really appreciate.
    Thanks again Alamgeer,
    Sincerely,
    Tiago

    Reply
  3. Jon P says:
    September 13, 2023 at 12:07 AM

    It would be incredible if you could show the whole solution. As a new person who understands this very little, these do not help much. Thank you for your time!

    Reply
    1. Learn Mobile Development says:
      October 7, 2023 at 6:02 PM

      Thanks Jon P for your comment, I have already provided solution link in end of this post.

      Reply
  4. Tony - Nhan Nguyen Lhoa Minh says:
    March 28, 2024 at 3:23 PM

    That would be an amazing solution. It’s easy to comprehend. Thank you 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 9+ 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 apply color to Images and Icons in MAUI
  • Xamarin Forms – The Latest CarouselView with IndicatorView
  • How to Prevent Dark Mode in Xamarin forms

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 0 0
Users Today : 6
Users Yesterday : 0
Users Last 7 days : 21
Users Last 30 days : 114
Users This Month : 62
Total views : 15311
How to Prevent Dark Mode in Xamarin forms
Trending
How to Prevent Dark Mode in Xamarin forms

Category

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

Contact Me

  • LinkedIn
      © 2026 Learn Mobile Development