CollectionView İçerisinde Swipe ve Drag&Drop İşlemleri

Merhaba,

Xamarin.Forms ile geliştirdiğimiz mobil uygulamalarımızda listeleme için kullandığımız CollectionView üzerinde çok fazla özelleştirilmiş işlem yapabiliyoruz. Bu yazımızda Swipe ve Drag & Drop işlemlerinin nasıl yapıldığını örneklendireceğiz. Varsayılan olarak bu iki özellik CollectionView içerisinde gelen özellikler değil, SwipeItems ve DragGestureRecognizer kontrollerini CollectionView içerisinde kullanacağız.

Çok basit bir list oluşturmamız gerekiyor. Öncelikle bu listeminizin class’ını oluşturalım.

    public class ItemModel : INotifyPropertyChanged
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Image { get; set; }
        private bool _fav;
        public bool Fav
        {
            get
            {
                return _fav;
            }
            set
            {
                _fav = value;
                RaisePropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        void RaisePropertyChanged([CallerMemberName] string prop = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
        }
    }

Sayfamızdaki işlemler için ViewModel sınıfımızı yazalım

    public class MainPageViewModel
    {
        private IList<ItemModel> _list;
        public IList<ItemModel> List
        {
            get
            {
                if (_list == null)
                    _list = new ObservableCollection<ItemModel>();
                return _list;
            }
            set
            {
                _list = value;
            }
        }

        void Bind()
        {
            List.Clear();
            for (int i = 1; i <= 10; i++)
            {
                List.Add(new ItemModel
                {
                    Id = i,
                    Name = Guid.NewGuid().ToString(),
                    Image = $"https://picsum.photos/id/{i}/200/300?grayscale&blur=2"
                });
            }
        }

        public ICommand FavoriteCommand => new Command((o) =>
        {
            if (o != null && o is ItemModel item)
            {
                item.Fav = !item.Fav;
            }
        });
        public ICommand DeleteCommand => new Command((o) =>
        {
            if (o != null && o is ItemModel item)
            {
                List.Remove(item);
            }
        });

        public MainPageViewModel()
        {
            Bind();
        }
    }

Sayfamızın xaml kodları

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:vm="clr-namespace:CW"
             xmlns:converter="clr-namespace:CW"
             x:Class="CW.MainPage">

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

    <ContentPage.Resources>
        <ResourceDictionary>
            <converter:FavBackgorundColorConverter x:Key="FavBackgorundColorConverter" />
        </ResourceDictionary>
    </ContentPage.Resources>
    
    <StackLayout>
        <CollectionView ItemsSource="{Binding List}"
                        x:Name="collectionView">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <SwipeView>
                        <SwipeView.LeftItems>
                            <SwipeItems>
                                <SwipeItem Text="Favorite"
                                           IconImageSource="favv.png"
                                           BackgroundColor="{Binding Fav, Converter={StaticResource FavBackgorundColorConverter}}"
                                           Command="{Binding Source={x:Reference collectionView}, Path=BindingContext.FavoriteCommand}"
                                           CommandParameter="{Binding}" />
                                <SwipeItem Text="Delete"
                                           IconImageSource="delete.png"
                                           BackgroundColor="Red"
                                           Command="{Binding Source={x:Reference collectionView}, Path=BindingContext.DeleteCommand}"
                                           CommandParameter="{Binding}" />
                            </SwipeItems>
                        </SwipeView.LeftItems>
                            <Grid BackgroundColor="White"
                                  Padding="10">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <Image Source="{Binding Image}"
                                   IsOpaque="True"
                                   Grid.Column="0"
                                   Grid.Row="0"/>
                            <Label Text="{Binding Name}"
                                   Grid.Column="1"
                                   Grid.Row="0"/>
                        </Grid>
                    </SwipeView>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </StackLayout>

</ContentPage>

Çok basit bir şekilde listeme yaptık ve Swipe işlemini test edebiliriz.

Favorite ve Delete işlemleri test ettiğimizde sorunsuz bir şekilde çalıştığını göreceğiz.

Listemize yeni bir item’i Drag & Drop özelliği ile ekleme yapalım.

Sayfamızın xaml kodlarını düzenliyoruz

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:vm="clr-namespace:CW"
             xmlns:converter="clr-namespace:CW"
             x:Class="CW.MainPage">

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

    <ContentPage.Resources>
        <ResourceDictionary>
            <converter:FavBackgorundColorConverter x:Key="FavBackgorundColorConverter" />
        </ResourceDictionary>
    </ContentPage.Resources>
    
    <StackLayout>
        <Label Text="New Item"
            x:Name="txtNewItem">
            <Label.GestureRecognizers>
                    <DragGestureRecognizer CanDrag="True"
                                           DragStartingCommand="{Binding DragStartingCommand}"
                                           DropCompletedCommand="{Binding DropCompletedCommand}"
                                           DropCompletedCommandParameter="{Binding Source={x:Reference txtNewItem}}"/>
                </Label.GestureRecognizers>
        </Label>
        <CollectionView ItemsSource="{Binding List}"
                        x:Name="collectionView">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <StackLayout>
                        <StackLayout.GestureRecognizers>
                            <DropGestureRecognizer AllowDrop="True"
                                                   DragOverCommand="{Binding DragOverCommand}"
                                                   DropCommand="{Binding DropCommand}"/>
                        </StackLayout.GestureRecognizers>
                        <SwipeView>
                            <SwipeView.LeftItems>
                                <SwipeItems>
                                    <SwipeItem Text="Favorite"
                                           IconImageSource="favv.png"
                                           BackgroundColor="{Binding Fav, Converter={StaticResource FavBackgorundColorConverter}}"
                                           Command="{Binding Source={x:Reference collectionView}, Path=BindingContext.FavoriteCommand}"
                                           CommandParameter="{Binding}" />
                                    <SwipeItem Text="Delete"
                                           IconImageSource="delete.png"
                                           BackgroundColor="Red"
                                           Command="{Binding Source={x:Reference collectionView}, Path=BindingContext.DeleteCommand}"
                                           CommandParameter="{Binding}" />
                                </SwipeItems>
                            </SwipeView.LeftItems>
                            <Grid BackgroundColor="White"
                                  Padding="10">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto" />
                                    <ColumnDefinition Width="*" />
                                </Grid.ColumnDefinitions>
                                <Image Source="{Binding Image}"
                                   IsOpaque="True"
                                   Grid.Column="0"
                                   Grid.Row="0"/>
                                <Label Text="{Binding Name}"
                                   Grid.Column="1"
                                   Grid.Row="0"/>
                            </Grid>
                        </SwipeView>
                    </StackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </StackLayout>

</ContentPage>

ViewModel içerisine Commandlarımızı yazıyoruz

public ICommand DragStartingCommand => new Command((o) =>
        {
            
        });
        public ICommand DropCompletedCommand => new Command((o) =>
        {
            if (o != null && o is Label l)
            {
                var id = List.Max(i => i.Id) + 1;
                List.Add(new ItemModel
                {
                    Fav = true,
                    Name = l.Text,
                    Image = $"https://picsum.photos/id/{id}/200/300?grayscale&blur=2",
                    Id = id
                });
            }
        });
        public ICommand DragOverCommand => new Command((o) =>
        {
            
        });
        public ICommand DropCommand => new Command((o) =>
        {
            
        });

Yeni bir item eklediğimiz fav = true şekilde eklenmiş olacaktır.

Kaynak kodlar : https://github.com/ozaksuty/CollectionView-erisinde-Swipe-ve-Drag-Drop-lemleri

Yiğit

Xamarin Developer, Consultant & Architect. Community Leader and Director of Xamarin Türkiye

Post A Reply