Liaison personnalisée MvvmCross UITextField

J’essaie donc d’implémenter une liaison personnalisée pour un UITextField dans MvvmCross, à peu près dans les lignes de la touche Binding ‘GO’ sur le clavier logiciel , c’est-à-dire en essayant de lier un champ de texte pour déclencher automatiquement un événement lorsque le bouton Terminé est activé. clavier (donc contraignant pour ShouldReturn ). J’ai également besoin de lier les événements EditingDidBegin et EditingDidEnd du champ de EditingDidBegin . Comme je lie plusieurs événements, j’ai créé un MvxPropertyInfoTargetBinding comme suit:

 public class MyTextFieldTargetBinding : MvxPropertyInfoTargetBinding { private ICommand _command; protected UITextField TextField { get { return (UITextField)Target; } } public MyTextFieldTargetBinding(object target, PropertyInfo targetPropertyInfo) : base(target, targetPropertyInfo) { TextField.ShouldReturn += HandleShouldReturn; TextField.EditingDidBegin += HandleEditingDidBegin; TextField.EditingDidEnd += HandleEditingDidEnd; } private bool HandleShouldReturn(UITextField textField) { if (_command == null) { return false; } var text = textField.Text; if (!_command.CanExecute (text)) { return false; } textField.ResignFirstResponder(); _command.Execute(text); return true; } private void HandleEditingDidBegin (object sender, EventArgs e) { // do something } private void HandleEditingDidEnd (object sender, EventArgs e) { // do something } public override MvxBindingMode DefaultMode { get { return MvxBindingMode.OneWay; } } public override void SetValue(object value) { var command = value as ICommand; _command = command; } public override Type TargetType { get { return typeof(ICommand); } } protected override void Dispose(bool isDisposing) { if (isDisposing) { if (TextField != null) { TextField.ShouldReturn -= HandleShouldReturn; TextField.EditingDidBegin -= HandleEditingDidBegin; TextField.EditingDidEnd -= HandleEditingDidEnd; } } base.Dispose(isDisposing); } 

}

Ma première question est la suivante: ai-je raison de créer un MvxPropertyInfoTargetBinding pour tous les événements? De même, je ne comprends pas la différence entre MvxPropertyInfoTargetBinding et MvxTargetBinding . Selon MVVMCross Lier décimal à UITextField supprime le point décimal utilisé pour remplacer une liaison existante, le dernier pour les propriétés connues et les paires d’événements. Alors, est-ce que j’utilise le bon?

Deuxièmement (et le nœud de mon problème), mon code fonctionne à l’ exception de SetValue – il est déclenché, mais la value est null . Voici ce que j’ai dans mon fichier d’ Setup :

 protected override void FillTargetFactories (IMvxTargetBindingFactoryRegistry registry) { base.FillTargetFactories (registry); registry.RegisterPropertyInfoBindingFactory(typeof(MyTextFieldTargetBinding), typeof(UITextField), "Text"); } 

Je ne fais rien dans mon sharepoint View – c’est peut-être là que réside le problème?

MODIFIER:

Mon ViewModel :

 public class LoginViewModel : MvxViewModel { private ssortingng _username; public ssortingng Username { get { return _username; } set { _username = value; RaisePropertyChanged(() => Username); } } private ssortingng _password; public ssortingng Password { get { return _password; } set { _password = value; RaisePropertyChanged(() => Password); } } private MvxCommand _login; public ICommand Login { get { _login = _login ?? new MvxCommand(DoLogin); return _login; } } public LoginViewModel(ILoginManager loginManager) { _loginManager = loginManager; } private void DoLogin() { // call the login web service } } 

Dans mon `View ‘, je ne fais rien d’extraordinaire (je crée les éléments View dans un fichier XIB):

 public override void ViewDidLoad() { base.ViewDidLoad (); this.NavigationController.SetNavigationBarHidden(true, false); var set = this.CreateBindingSet(); set.Bind(usernameTextField).To(vm => vm.Username); set.Bind(passwordTextField).To(vm => vm.Password); set.Bind (loginButton).To (vm => vm.Login); set.Apply(); } 

Pas de messages de trace intéressants.

1. Quelle est la particularité de PropertyInfoTargetBinding?

La question à laquelle vous faites référence – MVVMCross Binding décimale à UITextField supprime le point décimal – donne la clé de la différence entre MvxTargetBinding et MvxPropertyInfoTargetBinding :

  • TargetBinding peut être utilisé pour toute liaison arbitraire – par exemple, pour a non-propertyInfo-based binding liaison a non-propertyInfo-based binding
  • PropertyInfoTargetBinding hérite de TargetBinding et ne peut être utilisé qu’avec les propriétés C # réelles, car il utilise PropertyInfo via Reflection.

Dans votre cas, étant donné que vous n’utilisez pas réellement la propriété Text via Reflection, je serais tenté de ne pas utiliser PropertyInfoTargetBinding et d’éviter également le nom du Text ; écrivez plutôt un TargetBinding personnalisé.

le premier est utilisé lors du remplacement d’une liaison existante

Ce n’est certainement pas vrai – toute liaison peut être utilisée pour remplacer une autre liaison – comme le dit la réponse à l’autre question

MvvmCross utilise un système simple de «derniers gains gagnés»

Pour plus d’informations sur les liaisons personnalisées, consultez:


2. Pourquoi ma valeur SetValue devient-elle nulle?

Votre code de liaison actuel demande une ICommand:

 public override Type TargetType { get { return typeof(ICommand); } } 

Mais votre code View lie actuellement la vue à une ssortingng :

 // View set.Bind(usernameTextField).To(vm => vm.Username); // ViewModel private ssortingng _username; public ssortingng Username { get { return _username; } set { _username = value; RaisePropertyChanged(() => Username); } } 

Pour résoudre ce problème …

  1. Déterminez ce que vous souhaitez associer – s’agit-il d’une ICommand (par exemple, et MvxCommand) ou d’une ssortingng ?
  2. Changez la vue et la liaison pour refléter cela.