I am trying to handle something similar (from a user interface perspective) so that: 
to invoke two different business logic for:
- tapping on the ViewCell element itself (inside the ListView) - in the example, go to another page
- clicking on the Label element ( Clickable Label ), which is located inside the specified ViewCell element - in the example, delete this object or smth else
I would like to have a whole βtappingβ logic inside the ViewModel page.
Based on the Xamarin forum, I can cause some logic to βclickβ my action to remove from the cell, however, right inside my data model, which in my software is not a good solution, since I would like to manipulate the List (so the most preferred way was would have this logic on the ViewModel page).
What I have right now:
My View XAML Code page is as follows:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="App.Views.TestView"> <ContentPage.Content> <StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"> <ListView HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" ItemsSource="{Binding MyItemsCollection}" SelectedItem="{Binding SelectedItem}"> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <StackLayout Orientation="Horizontal"> <Label Text="{Binding Name}" VerticalOptions="CenterAndExpand" HorizontalOptions="StartAndExpand" /> <Label Text="Clickable Label" VerticalOptions="CenterAndExpand" HorizontalOptions="EndAndExpand"> <Label.GestureRecognizers> <TapGestureRecognizer Command="{Binding OnClickableLabel}" CommandParameter="{Binding .}" /> </Label.GestureRecognizers> </Label> </StackLayout> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView> </StackLayout> </ContentPage.Content> </ContentPage>
My View C # code page looks (and not specific code there, except for binding ** BindingContext * to the ViewModel page):
public partial class TestView : ContentPage { public TestView() { InitializeComponent(); BindingContext = ServiceLocator.Current.GetInstance<TestViewModel>(); } }
My page C # ViewModel Code is as follows:
public class TestViewModel : ViewModelBase { public TestViewModel() { MyItemsCollection = GetMyItemsCollection(); } private List<MyItem> GetMyItemsCollection() { return new List<MyItem> { new MyItem { ID = 1L, Name = "Item 1 Name" }, new MyItem { ID = 2L, Name = "Item 2 Name" }, new MyItem { ID = 3L, Name = "Item 3 Name" } }; } private List<MyItem> _myItemsCollection { get; set; } public List<MyItem> MyItemsCollection { get { return _myItemsCollection; } set { _myItemsCollection = value; RaisePropertyChanged(); } } private MyItem _SelectedItem { get; set; } public MyItem SelectedItem { get { return _SelectedItem; } set { if (_SelectedItem != value) { _SelectedItem = value; RaisePropertyChanged(); Debug.WriteLine("SelectedItem: " + _SelectedItem.Name); } } } private RelayCommand<object> _OnClickableLabel; public RelayCommand<object> OnClickableLabel { get { return _OnClickableLabel ?? (_OnClickableLabel = new RelayCommand<object>((currentObject) => Test(currentObject))); } } private void Test(object currentObject) { Debug.WriteLine("This should work... but it not working :("); } }
My model code as follows:
public class MyItem { public long ID { get; set; } public string Name { get; set; } private RelayCommand<object> _OnClickableLabel; public RelayCommand<object> OnClickableLabel { get { return _OnClickableLabel ?? (_OnClickableLabel = new RelayCommand<object>((currentObject) => Test(currentObject))); } } private void Test(object currentObject) { Debug.WriteLine("This works... but it not good idea, to have it here..."); } }
Any idea what needs to be changed to call OnClickableLabel directly on my ViewModel page? I know this is something wrong:
<TapGestureRecognizer Command="{Binding OnClickableLabel}" CommandParameter="{Binding .}" />
but I donβt know what: /.
Help! Many thanks.