J’essaie de lier un événement à un ListView, sur ma page de menu, en utilisant la propriété itemtapped. Actuellement, j’utilise le framework MVVM (Xamarin Form Labs) dans mon application. Ce que j’essaie d’accomplir, c’est lorsqu’un utilisateur appuie sur l’élément de menu pour que l’application accède à la vue correcte.
Voici le code xaml:
//setup template here
Je veux lier l’événement itemtapped à cette fonction:
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; }
Je peux actuellement obtenir que cela fonctionne si j’ajoute la fonction au code de la vue derrière et que je règle ensuite ItemTapped = ‘NavigatTo ‘, mais cela semble erroné car il met en échec le concept de MVVM. Ce que je veux vraiment faire est de lier à l’événement cette même fonctionnalité dans mon ViewModel, quelque chose comme ceci:
// this binding is to the ViewModel
Cependant, cela ne fonctionne pas ou je ne le fais pas correctement. Lorsque j’essaie de l’implémenter de cette façon, le code produit et une erreur.
Erreur: Xamarin.Forms.Xaml.XamlParseException: Aucune propriété du nom ItemTapped trouvée dans Xamarin.Forms.Xaml.BaseValueNode.SetPropertyValue
J’ai suivi la même architecture, créé un contrôle de liste personnalisé et créé une propriété pouvant être liée avec une commande que j’ai remplacée dans mon modèle de vue à l’aide du code ci-dessous:
Page de contrôle personnalisé [.cs] dans mon PCL
using System; using System.Windows.Input; using Xamarin.Forms; namespace YourNS { public class ListView : Xamarin.Forms.ListView { public static BindableProperty ItemClickCommandProperty = BindableProperty.Create(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; } } } }
Ma page XAML
Et dans mon modèle de vue [Dans cet exemple, je n’ai ouvert que la feuille d’action de la boîte de dialog
private Command selectCmd; public Command Select { get { this.selectCmd = this.selectCmd ?? new Command (s => this.dialogs.ActionSheet(new ActionSheetConfig() .Add("View", () => { if (!this.fileViewer.Open(s.FilePath)) this.dialogs.Alert(Ssortingng.Format("Could not open file {0}", s.FileName)); }) .Add("Cancel") ) ); return this.selectCmd; } }
Sinon, vous pouvez utiliser un comportement attaché
public static class ListViewAttachedBehavior { public static readonly BindableProperty CommandProperty = BindableProperty.CreateAttached ( "Command", typeof(ICommand), typeof(ListViewAttachedBehavior), null, propertyChanged:OnCommandChanged); static void OnCommandChanged (BindableObject view, object oldValue, object newValue) { var entry = view as ListView; if (entry == null) return; entry.ItemTapped += (sender, e) => { var command = (newValue as ICommand); if(command == null) return; if(command.CanExecute(e.Item)) { command.Execute(e.Item); } }; } }
Puis appelez-le sur votre liste