2013-07-16 6 views
4

Comment fonctionne le ClearBindings() dans MvvmCross? En ce qui concerne les tests, j'essaie simplement d'effacer les itemsSource de TableView dans ViewDidLoad() pour WeekSelectorView. Voici ce que j'ai essayé, mais rien ne semble fonctionner.MVVMCross: ClearBindings() - Comment utiliser Touch?

("ce" fait référence à mon instance actuelle de WeekSelectorView)

var source = new WeekSelectorTableSource(TableView, this); 
TableView.Source = source; 

var set = this.CreateBindingSet<WeekSelectorView, WeekSelectorViewModel>(); 
set.Bind(source).To(vm => vm.Options); 
set.Apply(); 

//None of these work 
this.ClearBindings (this); 
this.ClearBindings (source); 
this.ClearBindings (TableView.Source); 
this.ClearBindings (source.ItemsSource); 
this.ClearBindings ("ItemsSource"); 
this.ClearBindings ("source.ItemsSource"); 
this.ClearBindings ("TableView"); 
this.ClearBindings ("TableView.Source"); 
this.ClearBindings (TableView); 
this.ClearBindings ("TableView.Source.ItemsSource"); 
this.ClearBindings (set); 
this.ClearBindings ("set"); 
this.ClearBindings ("Options"); 

TableView.ReloadData(); 

Actuellement, quand je charge l'application, mon WeekSelectorView charge la table à base de données de mon ViewModel. Je veux effacer la liaison, donc il ne devrait pas y avoir de table du tout.

this.ClearAllBindings(); 

La ligne ci-dessus fonctionne, mais je ne veux pas effacer toutes les liaisons, je veux juste effacer ItemsSource de mon TableView.


Edit:

J'ai actuellement un WeekSelectorView qui a un .xib qui lui est associée. Dans le .xib est un TableView (parmi d'autres contrôles utilisateur).

Mon WeekSelectorView définit la source à ma propre classe "WeekSelectorTableSource". Cette classe de tablesource détermine le nombre de lignes/sections en fonction de la liaison ItemsSource. Il crée ensuite certaines cellules .xib sur mesure et dans mon GetOrCreateCellsFor

protected override UITableViewCell GetOrCreateCellFor(UITableView tableView, NSIndexPath indexPath, object item) 
    { 
     var weekSelectorCell = WeekSelectorCell.Create(); 

     var set = _WeekSelectorView.CreateBindingSet<WeekSelectorView, WeekSelectorViewModel>(); 

     //Using string bindings since bindings with an index doesn't work 
     //ex: vm => vm.Options[indexPath.Row].Title 
     set.Bind(weekSelectorCell).For(wc => wc.Title).To(string.Format("{0}{1}{2}", Options, indexPath.Row, Title)).OneWay(); 
     set.Bind(weekSelectorCell).For(wc => wc.Date).To(string.Format("{0}{1}{2}", Options, indexPath.Row, DateString)).OneWay(); 
     set.Bind(weekSelectorCell).For(wc => wc.Hours).To(string.Format("{0}{1}{2}", Options, indexPath.Row, TotalHours)).WithConversion(new HoursDecimalToHoursMinutesConverter(), null).OneWay(); 
     set.Apply(); 

     return weekSelectorCell; 
    } 

Maintenant, la raison pour laquelle je veux ClearBindings() ......

Chaque fois que je recharge la table, mes liaisons précédentes persistent. Donc, si je lie 4 cellules avec 3 liaisons chacune, la première fois que mon application aura 12 liaisons associées aux cellules. Une fois que je recharge la table (toujours avec 4 cellules), il y aura 24 liaisons .... puis 36, 48, etc.

Voici une partie des diagnostics ....

2013-07-16 16:26:03.950 FCXiOSv2[569:21e03] MvxBind: Warning: 1259.41 Weak Target is null in MvxWithEventPropertyInfoTargetBinding - skipping set 
2013-07-16 16:26:03.951 FCXiOSv2[569:21e03] MvxBind: Diagnostic: 1259.41 Receiving setValue to Week 
2013-07-16 16:26:03.952 FCXiOSv2[569:21e03] MvxBind: Warning: 1259.42 Weak Target is null in MvxWithEventPropertyInfoTargetBinding - skipping set 
2013-07-16 16:26:03.953 FCXiOSv2[569:21e03] MvxBind: Diagnostic: 1259.42 Receiving setValue to 7/8/13 - 7/14/13 
2013-07-16 16:26:03.954 FCXiOSv2[569:21e03] MvxBind: Warning: 1259.42 Weak Target is null in MvxWithEventPropertyInfoTargetBinding - skipping set 

Je suis Après avoir rechargé ma table, je me suis effondré avec ce message, donc j'ai voulu effacer mes liens à chaque fois avant que je ne commence TableView.ReloadData().


Edit:

Après avoir réfléchi et parler avec un collègue de travail qui travaille avec des liaisons natifs de Windows, j'ai découvert qu'il y avait beaucoup de choses que je faisais mal, histoire courte, je ne » t besoin d'utiliser ClearBindings(view).

J'avais ma vue la plus à l'extérieur manipulant toute la liaison, ainsi qu'une vue a été rechargée (alias des cellules dans une table), les liaisons persistaient encore parce que la vue extérieure n'avait pas été désaffectée. Donc, toutes mes sous-vues n'ont jamais géré leurs propres liaisons, ce qui était une erreur majeure.

Pour fixer ce changement (à la façon « correcte » j'imagine) que j'avais mon Hériter de cellule personnalisée à partir MvxTableViewCell et ajouté un délai contraignant. J'ai essayé avant

public WeekSelectorCell (IntPtr handle) : base (handle) 
{ 
    this.DelayBind (() => 
    { 
     var set = this.CreateBindingSet<WeekSelectorCell, WeekViewModel>(); 
     set.Bind(DateLabel).For(lbl => lbl.Text).To(vm => vm.DateString); 
     set.Bind(HoursLabel).For (lbl => lbl.Text).To(vm => vm.TotalHours).WithConversion(new HoursDecimalToHoursMinutesConverter(), null); 
     set.Bind(TitleLabel).For(lbl => lbl.Text).To(vm => vm.Title); 
     set.Apply(); 
    }); 
} 

mais a essayé de créer un ensemble entre <WeekSelectorCell, WeekSelectorViewModel> et a essayé d'accéder (vm => vm.Options [ROW] .Date), mais cela a toujours échoué.J'ai finalement appris que je devais créer un ensemble entre <WeekSelectorCell, WeekViewModel> parce Options[] est un ObservableCollection de WeekViewModel

Comme je l'ai dit, longue histoire courte, je ne ai pas besoin d'utiliser ClearBindings(view)

+0

Merci pour la longue histoire - très utile ... Je pense toujours qu'il pourrait y avoir d'autres cas où supprimer des liaisons pourrait être utile (c'était l'intention originale de la méthode droid 'ClearBindings (view)' - donc cela apparaîtra probablement dans la version iOS bientôt! Merci d'aider :) – Stuart

Répondre

3

Comment le ClearBindings() travailler dans MvvmCross?

ClearBindings() est ClearBindings(view)

Chaque MvxBindingContext maintient 3 listes distinctes des 'liaisons':

  1. une liste des raccourcis créés directement sur le contexte
  2. une table de consultation sur la base vue-des consolidations créés dans les vues enfant - ils ne sont actuellement utilisés que dans les liaisons Android lorsque les vues enfant sont dynamiquement gonflées dans le contexte de liaison parent.
  3. une liste d'actions (qui vont généralement pour créer des liaisons) qui sont en attente pour le premier appel à DataContext=value

Le premier est actuellement le principal utilisé dans iOS - et la seule API publiques parfaitement claires que MvxBindingContext expose pour cette liste est ClearAll.

Le second est utilisé uniquement dans Android pour certaines inflations Xml vue enfant - et ClearBindings(view) permet à ceux-ci d'être utilisés pour cela. L'histoire derrière tout cela est particulièrement liée à beaucoup de problèmes avec la gestion de la mémoire à la fois Android et iOS - en particulier pour s'assurer que nous suivions et éliminions toutes les liaisons, y compris celles créées dans les sous-vues, dans les listes, etc. .


Si nous pouvons creuser un bon cas d'utilisation ici ici - quelque chose d'un peu passée de « cela ne concerne que des fins de test » - puis une API ClearBindingsForObject ou EnumerateBinding serait quelque chose qui pourrait être considéré comme un API de contexte de liaison étendue - mais il faudrait certainement une exigence plus forte pour s'assurer que le projet a capturé ce pour quoi l'API est vraiment utile. En attendant, je suppose que vous pourriez créer et enregistrer la liaison en utilisant la tableView comme une recherche si vous le souhaitez - par exemple. quelque chose comme:

var bindings = MvxBindingSingletonCache.Instance.Binder.Bind(BindingContext.DataContext, tableView, "ItemsSource MySource"); 
this.RegisterBindingsFor(tableView, bindings); 

Ce serait alors vous permettre d'appeler ClearBindings(tableView);


Alternativement, si vous vouliez arrêter une personne de liaison de travail alors vous pourriez Dispose tôt - que le dissiperait est binding Source - par exemplesi vous avez fait:

_myDisposableBindings = MvxBindingSingletonCache.Instance.Binder.Bind(BindingContext.DataContext, tableView, "ItemsSource MySource"); 
    this.AddBindings(_myDisposableBindings); 

alors vous pourriez à un moment donné faire plus tard quelque chose comme:

foreach (var binding in _myDisposableBindings) 
    { 
     binding.Dispose(); 
    } 
    _myDisposableBindings = null; 

Sinon - et peut-être cela est la façon dont je vais (bien que cela dépende exactement quel est votre cas d'utilisation) - alors il pourrait être plus facile de placer votre table dans son propre contrôle MvxView - qui peut avoir son propre BindingContext que vous pouvez appeler ClearAllBindings() sur.

Pour en savoir plus sur MvxView voir http://slodge.blogspot.co.uk/2013/06/n32-truth-about-viewmodels-starring.html


Enfin, je pourrais aussi envisager de travailler si oui ou non vous pouvez simplement garder la liaison en place, mais pourrait plutôt effacer le ItemsSource dans votre ViewModel.

+0

vraiment fasciné par ce sujet - ont créé le problème de suivi - https://github.com/slodge/MvvmCross/issues/358 - Je pense principalement à des interfaces utilisateur dynamiques, mais aussi intéressé par ce domaine de compensation des liaisons sur les contrôles statiques aussi (juste pas tout à fait comprendre le cas d'utilisation) – Stuart