SfListView doesn't support well draging

Hello,

I've got a simple SfListView linked to a ObservableCollection (EditingRooms).
I've enable dragging object to re-order the list.
As I use grouping also, I can't use DragDropController.UpdateSource to auto-update my collection (as you answered me previously).
So I tried to manually update my collection on draging event  with this simple code :

private void ListView_ItemDragging(object sender, ItemDraggingEventArgs e) {
    // Reorder the item in underlying collection.
    if (e.Action == DragAction.Drop && e.OldIndex != e.NewIndex) {
        EditingRooms.Move(e.OldIndex, e.NewIndex);
    }
}

When I drag an item, the collection is correctly updated, but the SfListView show the previous state (before re-ordering). If I force an update by clearing ItemSource and reseting it, it shows the correct order. So the SfListView doesn't handle correctly the move.

I also have a delete feature that works great, with a simple EditingRooms.Remove(...), that's why I think it's a bug on your side.

Do you have a solution please ?
Thanks

5 Replies

RS Rawoof Sharief Muthuja Sherif Syncfusion Team May 14, 2018 12:57 PM UTC

Hi Tomas, 

We have checked the reported query from our side, can you please follow the incident created under this account for the same query. 

Regards, 
Rawoof M. 



TH Thomas June 8, 2018 03:03 PM UTC

Hello,

For the record, the Move() function just need  to be called AFTER ListView_ItemDragging has returned to allow SF component to finish his job.
So either use "Device.BeginInvokeOnMainThread" or "await Task.Delay(100)".

Also, when grouping is enabled, you can update the underlying collection based on ListViewControl.DataSource.DisplayItems by excluding group headers, if your collection is pre-sorted by group rules.


RS Rawoof Sharief Muthuja Sherif Syncfusion Team June 11, 2018 09:21 AM UTC

Hi Thomas, 
 
Thanks for the update. 
 
Regards, 
Rawoof M. 



AD Adam December 14, 2019 03:30 PM UTC

I know this is an old post and not related to the MVVM pattern, but there's not much verbiage out there for the issue Thomas incurred. Similar to his issue, when you bind an ObservableCollection to a drag-enabled SfListView the underlying collection doesn't update properly because setting SfListView.DragDropController.UpdateSource == true in the view (i.e. xaml) does nothing. You might think to manually update the collection with the SfListView.ItemDragging event by calling ObservableCollection.Move(ItemDraggingEventArgs.OldIndex, ItemDraggingEventArgs.NewIndex). Given that we're talking about an ObservableCollection, reordering items in the view-model should propagate to the view automatically, but I'm telling you the order is out of whack, which probably brought you here in the first place.

The best workaround I could think up is to set the UpdateSource property from the view-model, when the SfListView.Loaded event fires. Here's a condensed example from my project. In this case I'm using the Prism framework.
---------------------------------
EventPage.xaml
xmlns:prismBehaviors="clr-namespace:Prism.Behaviors;assembly=Prism.Forms"
xmlns:sfListView="clr-namespace:Syncfusion.ListView.XForms;assembly=Syncfusion.SfListView.XForms"
...
            sfListView:SfListView
                        x:Name="stopsListView"
                        AllowSwiping="True"
                        DragStartMode="OnDragIndicator"
                        ItemsSource="{Binding Stops}">
                            ...
                        sfListView:SfListView.Behaviors
                            <prismBehaviors:EventToCommandBehavior
                                Command="{Binding StopListViewLoadedCommand}"
                                CommandParameter="{Binding Source={x:Reference stopsListView}}"
                                EventName="Loaded" />
                       ...
            ...
---------------------------------
EventPageVM.cs
public EventPageVM()
{
            StopListViewLoadedCommand = new DelegateCommand<SfListView>((stopsListView) => stopsListView.DragDropController.UpdateSource = true);
}

public DelegateCommand<SfListView> StopListViewLoadedCommand { get; }

public ObservableCollection Stops { get; } = new ObservableCollection();


GS Gokul Saravanan Syncfusion Team December 16, 2019 05:16 PM UTC

Hi Adam, 
 
Thank you for contacting Syncfusion support.  
 
We have checked with a simple sample with the suggested work around to solve the query "Reorder underlying collection on Drag and drop items",  it works fine when grouping was disabled. If grouping is enabled then the UpdateSource will update the GroupDescriptor Property name which you have used to group the items. It will not update the underlying collection, which was the limitation that we mentioned in our documentation. 
 
 
We would like to let you know that you can update underlying collection when grouping was enabled using Itemdragging event in SfListView. After dropping the item we will get the dropped index, using that we will update the source collection after dropping the item. You need move the underlying collection based on the new index and old index obtained from item dragging event args.  
 
Please refer the below code example for the same. 
  
Code Example[C#]:    
private async void ListView_ItemDraggingAsync(object sender, ItemDraggingEventArgs e)    
{    
  if (e.Action == DragAction.Drop)    
  {    
    await Task.Delay(100);    
    ChangeData(e);    
  }    
}    
    
private void ChangeData(ItemDraggingEventArgs e)    
{    
   ViewModel.ToDoList.MoveTo(e.OldIndex, e.NewIndex);    
}    
    
Note: The solution works goodif the source collection is sorted according to group rules when Grouping is enabled. 
Regards, 
Gokul S

Loader.
Up arrow icon