- Home
- Forum
- Xamarin.Forms
- How to use ResetSwipe and conditionally disable swiping with sfListView and MVVM
How to use ResetSwipe and conditionally disable swiping with sfListView and MVVM
Hi, I hope you can help.
I am using sfListView with the MVVM model. The listview is using a RightSwipeTemplate and the user can take a photo using a command bound to a GestureReconizer:
<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Source={RelativeSource AncestorType={x:Type viewModels:TestResultViewModel}}, Path=TakePhotoCommand}" CommandParameter="{Binding .}" />
</Grid.GestureRecognizers>
I have two questions:
- When the user performs the command I want to close the swipe using ResetSwipe, however I have no access to the listview in the ViewModel. How can I achieve this?
- I want to conditionally disable/enable the swipe based on a property of the listview item. How can I do this in the MVVM and the ViewModel?
Thanks in advance.
SIGN IN To post a reply.
3 Replies
1 reply marked as answer
LN
Lakshmi Natarajan
Syncfusion Team
October 27, 2020 10:04 AM UTC
Hi Ian,
Thank you for using Syncfusion products.
We have checked the reported queries from our end.
#Regarding I want to conditionally disable/enable the swipe based on a property of the listview item
We would like to inform you that you can conditionally swipe the ListViewItem by cancelling the swipe in the SwipeStarted event. Please refer the following documentation regarding the same,
To achieve your requirement in MVVM, you can use EventToCommand behavior for SfListView. Please refer our user guidance document regarding the same from the following link,
Please refer the code snippets,
XAML: Bind SwipeStarted command using EventToCommand behavior
|
<syncfusion:SfListView x:Name="listView" ItemSpacing="1" AllowSwiping="True" AutoFitMode="Height" SelectionMode="None" ItemsSource="{Binding contactsinfo}">
<syncfusion:SfListView.Behaviors>
<local:EventToCommandBehavior EventName="SwipeStarted" Command="{Binding SwipeStartedCommand}"/>
</syncfusion:SfListView.Behaviors>
<syncfusion:SfListView.ItemTemplate >
<DataTemplate>
<Grid x:Name="grid" BackgroundColor="{Binding BackgroundColor}">
...
</Grid>
</Grid>
</DataTemplate>
</syncfusion:SfListView.ItemTemplate>
...
</syncfusion:SfListView> |
ViewModel: You can get the SwipeStartedEventArgs from the command parameter and cancel the swiping using Cancel property based on the condition.
|
public class ContactsViewModel : INotifyPropertyChanged
{
public ObservableCollection<Contacts> contactsinfo { get; set; }
public Command<object> SwipeStartedCommand { get; set; }
private SfListView SfListView;
public ContactsViewModel()
{
contactsinfo = new ObservableCollection<Contacts>();
SwipeStartedCommand = new Command<object>(OnSwipeStarted);
GenerateInfo();
}
private void OnSwipeStarted(object obj)
{
var args = obj as Syncfusion.ListView.XForms.SwipeStartedEventArgs;
if ((args.ItemData as Contacts).BackgroundColor == Color.LightGray)
{
args.Cancel = true;
}
}
} |
#Regarding When the user performs the command I want to close the swipe using ResetSwipe
We would like to inform you that you can achieve your requirement by using the following code snippets,
XAML: Bind SwipeEnded command for SfListView and send listView instance as CommandParameter. This inturn breaks the MVVM in the other hand.
|
<syncfusion:SfListView x:Name="listView" ItemSpacing="1" AllowSwiping="True" AutoFitMode="Height" SelectionMode="None" ItemsSource="{Binding contactsinfo}">
<syncfusion:SfListView.Behaviors>
<local:EventToCommandBehavior EventName="SwipeEnded" Command="{Binding SwipeEndedCommand}" CommandParameter="{x:Reference listView}"/>
</syncfusion:SfListView.Behaviors>
<syncfusion:SfListView.ItemTemplate >
<DataTemplate>
...
</DataTemplate>
</syncfusion:SfListView.ItemTemplate>
<syncfusion:SfListView.RightSwipeTemplate>
<DataTemplate>
<Grid BackgroundColor="Black">
<Label Text="Right Swipe" TextColor="White" FontAttributes="Bold" VerticalTextAlignment="Center" HorizontalTextAlignment="Center"/>
<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Source={RelativeSource AncestorType={x:Type local:ContactsViewModel}}, Path=TakePhotoCommand}" CommandParameter="{Binding .}" />
</Grid.GestureRecognizers>
</Grid>
</DataTemplate>
</syncfusion:SfListView.RightSwipeTemplate>
</syncfusion:SfListView> |
ViewModel: In the SwipeEnded command method, get the ListView from the CommandParameter and set it to the ViewModel property. And, reset the swipe in the TakePhotoCommand method.
|
public class ContactsViewModel : INotifyPropertyChanged
{
public ObservableCollection<Contacts> contactsinfo { get; set; }
public Command<object> SwipeEndedCommand { get; set; }
public Command<object> TakePhotoCommand { get; set; }
private SfListView SfListView;
public ContactsViewModel()
{
contactsinfo = new ObservableCollection<Contacts>();
SwipeEndedCommand = new Command<object>(OnSwipeEnded);
TakePhotoCommand = new Command<object>(OnTakePhotoClicked);
GenerateInfo();
}
private void OnSwipeEnded(object obj)
{
SfListView = obj as SfListView;
}
private void OnTakePhotoClicked(object obj)
{
SfListView.ResetSwipe();
}
} |
We have prepared a sample for both of your requirements and attached in the following link,
Please let us know if you need further assistance.
Regards,
Lakshmi Natarajan
Marked as answer
IA
Ian
October 27, 2020 10:13 PM UTC
Hi Lakshmi,
Thanks very much for your help.
I've implemented your suggestions and all is working as required. It would be better if I didn't have a reference to the listview in the datamodel though. Perhaps a listview property could be added in the future to autoclose the swipe?
I've not experienced such fantastic support for many years. I'll certainly recommend Syncfusion.
Regards,
Ian
LN
Lakshmi Natarajan
Syncfusion Team
October 28, 2020 06:51 AM UTC
Hi Ian,
Sorry for the inconvenience caused.
You can get the swiped item data from the SwipeStartedEventArgs and maintain the data in the ViewModel instead of SfListView. And pass the listview instance to the CommandParameter. Please refer the following code snippets for more reference,
XAML
|
<syncfusion:SfListView x:Name="listView" ItemSpacing="1" AllowSwiping="True" AutoFitMode="Height" SelectionMode="None" ItemsSource="{Binding contactsinfo}">
<syncfusion:SfListView.Behaviors>
<local:EventToCommandBehavior EventName="SwipeStarted" Command="{Binding SwipeStartedCommand}"/>
</syncfusion:SfListView.Behaviors>
<syncfusion:SfListView.RightSwipeTemplate>
<DataTemplate>
<Grid BackgroundColor="Black">
<Label Text="Right Swipe" TextColor="White" FontAttributes="Bold" VerticalTextAlignment="Center" HorizontalTextAlignment="Center"/>
<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Source={RelativeSource AncestorType={x:Type local:ContactsViewModel}}, Path=TakePhotoCommand}" CommandParameter="{x:Reference listView}"/>
</Grid.GestureRecognizers>
</Grid>
</DataTemplate>
</syncfusion:SfListView.RightSwipeTemplate>
</syncfusion:SfListView> |
ViewModel
|
using Syncfusion.ListView.XForms;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace ListViewXamarin
{
public class ContactsViewModel : INotifyPropertyChanged
{
public ObservableCollection<Contacts> contactsinfo { get; set; }
public Command<object> SwipeStartedCommand { get; set; }
public Command<object> TakePhotoCommand { get; set; }
private Contacts SwipedItem;
public ContactsViewModel()
{
contactsinfo = new ObservableCollection<Contacts>();
SwipeStartedCommand = new Command<object>(OnSwipeStarted);
TakePhotoCommand = new Command<object>(OnTakePhotoClicked);
GenerateInfo();
}
private void OnTakePhotoClicked(object obj)
{
//Get the swiped item data from the SwipedItem property.
(obj as SfListView).ResetSwipe(); // Reset swipe
}
private void OnSwipeStarted(object obj)
{
var args = obj as Syncfusion.ListView.XForms.SwipeStartedEventArgs;
this.SwipedItem = args.ItemData as Contacts;
if (SwipedItem.BackgroundColor == Color.LightGray)
{
args.Cancel = true;
}
}
}
} |
Sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/159128_Modified-1314187117
Please let us know if you need further assistance.
Lakshmi Natarajan
SIGN IN To post a reply.