In a project I’m working on, there was a specific request for having a collection of SwipeViews on a page, where it is only possible to have a single SwipeView swiped open. Since I wasn’t able to find a proper solution for that on the web (only a request, for example here, I decided to write a short post about my solution. The example repo you can find here.
In the last few months, Xamarin HQ has been working on stabilizing the SwipeView. As David Ortinau announced in his latest blogpost, Xamarin Forms 5.0 promises a lot of bug resolves and hopefully so a stable version of this control.
In the current stable version of Xamarin Forms, this control is still in preview and developers need to set the Experimental Flags for the SwipeView in the native projects, as described in the documentation for the SwipeView.
For this project, I used a simple MVVM setup, so we need at least a Model, a View and a ViewModel to work with.
I will only use SwipeViews that open up on the right side, but you can implement this solution in every way you like for the SwipeView. I would say the possibilities are countless…
First thing I set up was the model, in this case a Person class with two properties. The IsOpen property is necessary to bind to the custom SwipeView I will explain later. I implemented the INotifyPropertyChanged interface to be able to notify the view about the IsOpen property updates.
Simply create a list of Persons as a source for the CollectionView. The DeleteCommand handles the SwipeView Delete button that shows up when swiping the item to the left. The OpenItemChangedCommand sets the IsOpen property of any other Person item, that is not the last swiped Person item, to false.
OnPropertyChanged() is needed to update the page when an item is deleted from the list.
In order to get the solution working, we need to extend the existing SwipeView with some properties of our own. In the official documentation for SwipeView, I have already seen a bindable property IsOpen, but in the current stable Xamarin version, you’re not yet able to use it. In this case I created a bindable IsOpen property that will be bound to the IsOpen property in the Person model. When that property changes, the Command will be executed. Also make sure to set the BindingMode to TwoWay, since we need to be able to update both the View and the ViewModel in both ways.
The SwipeView gives us the ability to subscribe to the SwipeEnded event. With the SwipeEndedEventArgs we’re able to check if the SwipeView is open when the swipe gesture has ended. This is the key of success to this implementation: if the SwipeView is open, the IsOpen property will be updated. This will update the IsOpen property for the swiped Person item AND will execute the command to make sure all other Person items in the list will have the IsOpen property set to false.
Last but not least, we need to create the page with the CollectionView. I used relative binding to be able to bind to the ViewModel from a DataTemplate. The model itself is bound as a CommandParameter to be able to update or delete the model from the list. Make sure to bind the Person.IsOpen property to the CustomSwipeView.IsOpen property.
This is my solution, I bet there are many other solutions. If you have one, let me know!