I am trying to bind an event to a ListView, on my menu page, using the itemtapped property. Currently I am using MVVM (Xamarin form labs) framework in my app. What I am trying to accomplish is when a user taps the menu item the app navigates to the correct view.
Here is the xaml code:
<ListView x:Name="list"
ItemsSource="{Binding MenuItems}"
SelectedItem="{Binding SelectedItem}"
ItemTapped= SET-BINDING-HERE >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
//setup template here
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I want to bind the itemtapped event to this function:
public void NavigateTo(object sender, ItemTappedEventArgs args)
{
var test = args.Item as MenuModel;
cPageTypes.GetByKey(test.CommandParameter)
.SwitchRootPage(AIMCore.ViewModels.ElliottBaseViewModel.MasterPage);
list.SelectedItem = null;
AIMCore.ViewModels.BaseViewModel.MasterPage.IsPresented = false;
}
I can currently get this to work if I add the function to the view's code behind and then set the ItemTapped='NavigatTo', but this seems wrong as it defeats the MVVM concept. What I really want to do is bind the event this same functionality in my ViewModel something like this:
<ListView x:Name="list"
ItemsSource="{Binding MenuItems}"
SelectedItem="{Binding SelectedItem}"
ItemTapped= "{Binding NavigateTo}" > // this binding is to the ViewModel
However this is not working or I am not doing it correctly. When I try implement it this way the code produces and error.
Error: Xamarin.Forms.Xaml.XamlParseException: No Property of name ItemTapped found at Xamarin.Forms.Xaml.BaseValueNode.SetPropertyValue
I've followed the same architecture and done through creating custom list control and created 1 bindable property with command which I've override in my View Model using below code:
Custom Control [.cs] page in my PCL
using System;
using System.Windows.Input;
using Xamarin.Forms;
namespace YourNS {
public class ListView : Xamarin.Forms.ListView {
public static BindableProperty ItemClickCommandProperty = BindableProperty.Create<ListView, ICommand>(x => x.ItemClickCommand, null);
public ListView() {
this.ItemTapped += this.OnItemTapped;
}
public ICommand ItemClickCommand {
get { return (ICommand)this.GetValue(ItemClickCommandProperty); }
set { this.SetValue(ItemClickCommandProperty, value); }
}
private void OnItemTapped(object sender, ItemTappedEventArgs e) {
if (e.Item != null && this.ItemClickCommand != null && this.ItemClickCommand.CanExecute(e)) {
this.ItemClickCommand.Execute(e.Item);
this.SelectedItem = null;
}
}
}
}
My XAML Page
<ContentPage ...
xmlns:local="clr-namespace:Samples.Views;assembly=Your Assebly Name">
<local:ListView ItemClickCommand="{Binding Select}"
ItemsSource="{Binding List}">
And in my View Model [In this example, I've only opened dialog action sheet
private Command<Signature> selectCmd;
public Command<Signature> Select {
get {
this.selectCmd = this.selectCmd ?? new Command<Signature>(s =>
this.dialogs.ActionSheet(new ActionSheetConfig()
.Add("View", () => {
if (!this.fileViewer.Open(s.FilePath))
this.dialogs.Alert(String.Format("Could not open file {0}", s.FileName));
})
.Add("Cancel")
)
);
return this.selectCmd;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With