2017-08-16 5 views
1

Je n'arrive pas à comprendre, comment puis-je lier deux propriétés personnalisées entre View et ViewMode avec le mode bidirectionnel. abord je dois un mêmes ViewModel semblable:Mvvmcross Liaison bidirectionnelle entre propriétés personnalisées

//ViewModel 
    public class MyViewModel : MvxViewModel 
    { 
    .... 

    private MyMode _testA 

    public MyMode TestA 
    { 
     get => _testA; 
     set { 
      _testA = value; 
      RaisePropertyChanged(()=> TestA); 
      } 
    } 


     public MyViewModel() 
     { 
      TestA = MyMode.A; 
     } 

      ........ 
    } 

Dans Voir Je ne lient avec ma propriété personnalisée:

//View 
public partial class MyView : MvxViewController<MyViewModel> 
{ 

    public MyMode UiTestA 

    private void SetBiding() 
     { 
      var set = this.CreateBindingSet<MyView, MyViewModel>(); 
      set.Bind(this).For(x => x.UiTestA()).To(vm => vm.TestA); 
      set.Apply(); 
     } 

    private void SomeMethod() 
     { 
      var t1 = UiTestA; // t1 = MyMode.A; 
      UiTestA = MyMode.B; // Two way binding? 
      var t2 = ViewModel.TestA; // MyMode.A; 
     } 
} 

Si je change Testa ViewModel, je peux obtenir cette perspective, je Voulez-vous le changer dans View et trouver une nouvelle valeur dans ViewModel.

+0

Pour clarifier ce Cheesebaron répondu, la raison pour laquelle la propriété VM n'a pas été mise à jour était parce que rien n'a déclenché une notification de modification du côté View. Dans votre machine virtuelle, vous utilisez RaisePropertyChanged. Du côté de la vue, vous allez créer TargetBinding comme ci-dessous. La raison pour laquelle Mvx fonctionne hors de la boîte est que des choses comme Text et Click ont ​​des liaisons déjà définies dans le framework Mvx. – Kiliman

Répondre

0

Par défaut, MvvmCross peut lier toutes les propriétés publiques, en mode OneWay. Pour que le mode TwoWay fonctionne, vous devez créer au niveau de la liaison cible ce qui permet de définir de la cible à la source. Ils sont appelés TargetBindings.

Disons que votre vue a une propriété appelée Hello et un événement appelé HelloChanged. Avec ces deux à la main, vous pouvez créer un simple TargetBinding:

public class MyViewHelloTargetBinding 
    : MvxConvertingTargetBinding 
{ 
    protected MyView View => Target as MyView; 

    private bool _subscribed; 

    public MyViewHelloTargetBinding(MyView target) 
     : base(target) 
    { 
    } 

    private void HandleHelloChanged(object sender, EventArgs e) 
    { 
     var view = View; 
     if (view == null) return; 

     FireValueChanged(view.Hello); 
    } 

    public override MvxBindingMode DefaultMode = MvxBindingMode.TwoWay; 

    public override void SubscribeToEvents() 
    { 
     var target = View; 
     if (target == null) 
     { 
      MvxBindingTrace.Trace(MvxTraceLevel.Error, 
       "Error - MyView is null in MyViewHelloTargetBinding"); 
      return; 
     } 

     target.HelloChanged += HandleHelloChanged; 
     _subscribed = true; 
    } 

    public override Type TargetType => typeof(string); 

    protected override void SetValueImpl(object target, object value) 
    { 
     var view = (MyView)target; 
     if (view == null) return; 

     view.Hellp = (string)value; 
    } 

    protected override void Dispose(bool isDisposing) 
    { 
     base.Dispose(isDisposing); 
     if (isDisposing) 
     { 
      var target = View; 
      if (target != null && _subscribed) 
      { 
       target.HelloChanged -= HandleHelloChanged; 
       _subscribed = false; 
      } 
     } 
    } 
} 

Ensuite, il vous suffit d'enregistrer votre objectif contraignant dans votre fichier Setup.cs dans FillTargetFactories:

registry.RegisterCustomBindingFactory<MyView>(
    "Hello", view => new MyViewHelloTargetBinding(view));