Maja Remic
Maja Remic

Reputation: 399

UWP: Use Move instead of Remove+Insert when reordering items in ListView

I'm using a ListView control bound to an ObservableCollection. I've setup the control to support reordering items inside the collection with the following settings:

<ListView
    AllowDrop="True"
    CanDragItems="True"
    CanReorderItems="True">
    ...
</ListView>

It all works nicely, except I've noticed that despite the source collection supporting the Move() method, the list view does Remove() + Insert() instead.

Problem is, I've also implemented Undo-Redo functionality on the collection by responding to CollectionChanged events. And since the list view performs two actions instead of one, I need to Undo twice to get to the state before the move. On the other hand, if I call the Move() method on the collection via code, only one Undo is needed (as it should be).

So my question is: How can I force the list view to use the Move() method?

Upvotes: 0

Views: 178

Answers (1)

Anran Zhang
Anran Zhang

Reputation: 7727

So my question is: How can I force the list view to use the Move() method?

The current ListView does not provide a property or method that supports this operation.

The data source of ListView is not necessarily ObservableCollection, it can be an array, List or other collection, and these collections may do not have Move() method.

But most collections are support the Remove and Insert methods. When the ListView performs data reordering, calling the Remove and Insert methods is the best choice.

The Move method of the ObservableCollection is also implemented based on this. According to the current open source .Net Core, I found the implementation of ObservableCollection.Move.

/// <summary>
/// Called by base class ObservableCollection&lt;T&gt; when an item is to be moved within the list;
/// raises a CollectionChanged event to any listeners.
/// </summary>
protected virtual void MoveItem(int oldIndex, int newIndex)
{
    CheckReentrancy();

    T removedItem = this[oldIndex];

    base.RemoveItem(oldIndex);
    base.InsertItem(newIndex, removedItem);

    OnIndexerPropertyChanged();
    OnCollectionChanged(NotifyCollectionChangedAction.Move, removedItem, newIndex, oldIndex);
}

And here is the implementation of the .Net Framework.(Almost the same)

Although UWP does not have open source, there is no fundamental difference.

It can be seen that even the ObservableCollection uses the Remove and Insert methods internally, so the ListView does not deliberately emphasize the use of the ObservableCollection.Move method to adjust the position of the elements in the collection.

Best regards.

Upvotes: 4

Related Questions