I'm trying to handle something similar (from UI perspective), to:
in order to invoke two different business logics for:
- tapping at ViewCell element itself (inside ListView) - in example navigate to different page
- tapping at Label element (Clickable Label), which is inside given ViewCell element - in example delete given object or smth else
I would like to have whole "tapping" logic inside page ViewModel.
Based on Xamarin forum proposes, I'm able to invoke some logic of "tapping" my delete action from cell, however directly inside my data model - which in my PoV is not good solution, as I would like to manipulate my List collection (so the most preferable way, would be to have this logic at page ViewModel).
What I have right now:
My page View XAML code looks like:
<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">
<!-- Name Label -->
<Label Text="{Binding Name}" VerticalOptions="CenterAndExpand" HorizontalOptions="StartAndExpand" />
<!-- Delete "Icon" -->
<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 page View C# code looks like (not specific code there, except binding **BindingContext* to page ViewModel):
public partial class TestView : ContentPage
{
public TestView()
{
InitializeComponent();
BindingContext = ServiceLocator.Current.GetInstance<TestViewModel>();
}
}
My page ViewModel C# code looks like:
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's not working :(");
}
}
My data model code looks like:
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's not good idea, to have it here...");
}
}
Any idea what needs to be changed, in order to invoke OnClickableLabel directly inside my page ViewModel ? I know, that it's something wrong at:
<TapGestureRecognizer Command="{Binding OnClickableLabel}" CommandParameter="{Binding .}" />
but don't know what :/.
Help! Thanks a lot.
MyItem
, fire it when the deletion label is clicked (using TapGestureRecognizer). subscribe to that event from anywhere, or in your case, from the ViewModel and handle those clicks in any way you want. – nicks