2017-03-08 1 views
0

Je simple flux de navigation suivante:MvvmCross Sur le dos d'un autre ViewModel

ViewModel1 => ViewModel2 => ViewModel3

Lorsque ViewModel3 est fermé, je publie avec le plugin Message à viewmodel certains informations qui doivent être ajoutées à la liste dans ViewModel1. Malheureusement, rien ne se passe (je lève NotifChanged). À mon avis, cela arrive parce que l'IU ne l'appelle pas.

Quelle est la meilleure façon d'obtenir une liste rafraîchissante? Je ne vois aucune méthode dans le ViewModel qui est appelée lorsque ViewModel est de retour d'un autre ViewModel, c'est-à-dire lorsque ViewModel3 est fermé.

EDIT: Exemple de code:

public class WarehouseInViewModel : MvxViewModel 
    { 
     public WarehouseInViewModel(IMvxMessenger messenger) 
     { 
      mvxMessenger = messenger; 
      myToken = mvxMessenger.Subscribe<mAcceptMessage>(OnMyMessageArrived); 

     } 

     public override void Start() 
     { 
      base.Start(); 

     } 


     private readonly IMvxMessenger mvxMessenger; 
     private MvxSubscriptionToken myToken; 

     private List<mProduct> productItems; 
     public List<mProduct> ProductItems 
     { 
      get { return productItems; } 
      set 
      { 
       productItems = value; 
       RaisePropertyChanged(() => ProductItems); 
      } 
     } 
     private MvxCommand<AcceptMenuItem> buttonCommand; 
     public ICommand ButtonCommand 
     { 
      get 
      { 
       return buttonCommand = buttonCommand ?? new MvxCommand<AcceptMenuItem>(MenuClick); 
      } 
     } 
     private void OnMyMessageArrived(mAcceptMessage myMessage) 
     { 
      mProduct product = mProduct.GetById(myMessage.ProductId); 
    //Something more ... 

    // There I want to update my Listview which is binded to ProductItems 
      ProductItems.Add(product); 

      RaisePropertyChanged(() => ProductItems); 
     } 
     public async void MenuClick(AcceptMenuItem menu) 
     { 
      ShowViewModel<WarehouseInScanViewModel>(); 
     } 

    } 

Et la méthode la plus importante de la troisième ViewModel (nous supposons que secont viewmodel ouvre seulement en troisième position, et il est fermé correctement)):

public void ButtonNextClick() 
    { 
     vxMessenger.Publish(new mAcceptMessage(this, productId, scannedLocation.Id, productQuantity)); 
        Close(this); 

    } 

Alors , quand je suis de retour de la troisième VM, je veux réorganiser ListView. Je ne peux pas le faire à partir de OnMyMessageArrived car ce n'est pas dans le thread de l'interface utilisateur.

+0

Pourriez-vous fournir un exemple de code? Vous pouvez également consulter cette [réponse Stackoverflow] (http://stackoverflow.com/questions/42441831/mvvmcross-how-to-raisepropertychange-from-another-viewmodel/42447761#answer-42447761) pour d'autres idées dans l'actualisation des données sur ViewModels transmis. – Plac3Hold3r

+0

@ Plac3Hold3r J'ai fourni un exemple de code. Je suis ouvert à d'autres solutions. J'ai pensé à une base de données simple pour stocker des produits, mais cela semble être une mauvaise solution. – straiser

+0

En résumé, voulez-vous dire que vous souhaitez ajouter des données de 'ViewModel3' à' ViewModel1' lorsque 'ViewModel3' est fermé? –

Répondre

0

Vous pouvez ajouter une classe statique GlobalVars.cs (créer probablement le dossier Services et le placer à l'intérieur pour qu'il soit plus propre) avec des champs statiques et l'utiliser comme source de données de votre liste dans ViewModel1. Ensuite, tout ce que vous devez faire est d'ajouter les données sur le List dans GlobalVars.cs de ViewModel3.

Services/GlobalVars.cs

public static class GlobalVars 
{ 
    public static List<CustomClass> aGlobalVariable; 
} 

ViewModel1.cs

using Services; 
... 
public CustomClass LocalVariable 
{ 
    get { return GlobalVars.aGlobalVariable; } 
    set 
    { 
     GlobalVars.aGlobalVariable = value; 
     ... 
    } 
} 

//refresh purpose 
public void refresh() 
{ 
    RaisePropertyChanged(() => LocalVariable); 
} 

ViewModel3.cs

//just add the GlobalVars List when you need it 
GlobalVars.aGlobalVariable.Add(new CustomClass()); 

Pour actualiser votre ListView, lorsque vous revenez au ViewModel1, il vous suffit d'appeler la méthode refresh() de l'activité. Voici comment accéder au ViewModel en activité.

View1.cs

ViewModel1 vm; 
... 
protected override void OnCreate(Bundle bundle) 
{ 
    base.OnCreate(bundle); 
    ... 
    vm = ViewModel as ViewModel1; 
    ... 
} 
//what you want to do is refreshing the list on resume 
protected override void OnResume() 
{ 
    base.OnResume() 
    vm.refresh(); 
    ... //other things you might want to do 
} 

espoir cette réponse pourrait vous aider.