2017-12-06 6 views
0

Ich habe 2 Ansichten und 2 Viewmodel:ReactiveUI Befehl Abmelde

First View:

public partial class FirstView : Page 
{ 
    FirstViewModel ViewModel; 
    public FirstView() 
    { 
     ViewModel = new FirstViewModel(); 
     ViewModel.ShowSecondView.Subscribe(_ => 
     {    
      NavigationService.Navigate(new SecondView(ViewModel.ChildViewModel)); 
     });    

     this.DataContext = ViewModel; 
     InitializeComponent();    
    }   
} 

Erstes Ansichtsmodell:

public class FirstViewModel 
{ 
    SecondViewModel ChildViewModel; 
    public ReactiveCommand<Unit, Unit> ShowSecondView { get; set; } 
    public FirstViewModel() 
    { 
     ChildViewModel = new SecondViewModel(); 
     ShowSecondView = ReactiveCommand.Create(() => 
     { 
      ChildViewModel.Reconfigure(...); 
     });   
    }   
} 

zweiten View:

public partial class SecondView : Page 
{ 
    SecondViewModel ViewModel; 
    public SecondView(SecondViewModel viewModel) 
    { 
     ViewModel = viewModel; 
     ViewModel.GoBack.Subscribe(_ => 
     { 
      DoSomethingHard(); 
      if(NavigationService != null) NavigationService.GoBack(); 
     }); 
     this.DataContext = ViewModel; 
     InitializeComponent();    
    }   
} 

Zweites Ansichtsmodell :

public class SecondViewModel 
{ 
    public ReactiveCommand<Unit, Unit> GoBack { get; set; } 
    public FirstViewModel() 
    { 
     VeryLongInitialization(); 
     GoBack = ReactiveCommand.Create(() => { });   
    }   
    public void Reconfigure(...) 
    { ... } 
} 

Also, wenn ich FirstViewModel.ShowSecondView mehrmals laufen und SecondViewModel.GoBack mehrmals ausgeführt werden, führen DoSomethingHard() auch mehrmals auf jeder erstellt SecondView.

Warum möchte ich ChildViewModel in FilstViewModel einmal erstellen? Weil das Erstellen von SecondViewModel lange dauert. Und ich nicht jedes Mal neu erstellen SecondViewModel, aber nur neu konfigurieren.

Meine Frage ist, wie kann ich ViewModel.GoBack.Subscribe in SecondView abmelden?

P.S. Vielleicht sollte ich nicht SecondView in FirstView neu erstellen, aber es neu konfigurieren sowie SecondViewModel?

UPDATE 1 (dank Julien Mialon)

I IDisposable goBackSubscr hinzufügen und es funktioniert! Habe ich recht, um es umzusetzen?

public partial class SecondView : Page 
{ 
    SecondViewModel ViewModel; 
    IDisposable goBackSubscr; 
    public SecondView(SecondViewModel viewModel) 
    { 
     ViewModel = viewModel; 
     goBackSubscr = ViewModel.GoBack.Subscribe(_ => 
     { 
      DoSomethingHard(); 
      if(NavigationService != null) NavigationService.GoBack(); 
      goBackSubscr.Dispose(); 
     }); 
     this.DataContext = ViewModel; 
     InitializeComponent();    
    }   
} 

Antwort

0

Dank @Krzysztof Skowronek

ich noch einmal über IViewFor lesen und lösen mein Problem

public partial class SecondView : Page, IViewFor<SecondViewModel> 
{ 
    public SecondViewModel ViewModel { get; set; } 
    object IViewFor.ViewModel { get => ViewModel; set { ViewModel = (SecondViewModel)value; } } 
    public SecondView(SecondViewModel viewModel) 
    { 
     ViewModel = viewModel; 
     this.WhenActivated(disposables => 
     { 
      ViewModel.GoBack.Subscribe(_ => 
       { 
        DoSomethingHard(); 
        if (NavigationService != null) NavigationService.GoBack(); 
       }) 
       .DisposeWith(disposables);    

      this.WhenAnyValue(p => p.ViewModel) 
       .BindTo(this, x => x.DataContext) 
       .DisposeWith(disposables); 
     });   
    InitializeComponent();    
    }   
} 
1

Verwendung WhenAcitvated auf Ihrer Ansicht: in Konstruktor Ihrer Seite (es hat IViewFor sein):

this.WhenActivated(
    disposables => 
    { 
     ViewModel.Command.Subscribe(...).(disposables); 
    }); 
+0

ich über IViewFor lesen, aber ich verstehe es nicht (unbedingt) –

1

Verfahren zeichnen ein IDisposable zurückkehren, sollten Sie es speichern und entsorgen, wenn Sie möchte sich abmelden.

+0

Ich habe UPDATE1 in Frage zu stellen –

0

Ich denke, ich weiß, was Sie versuchen zu tun. Wenn ich recht habe, versuchen Sie, einen Wizard irgendeiner Art oder etwas zu erstellen, das ein Ansichtsmodell anzeigt, das zum nächsten wechseln kann, und das kann dann vorher verschoben werden? Wenn das der Fall ist, dann möchten Sie vielleicht überdenken, wie Sie es tun. Beispiel: Verwalten Sie die Schaltflächen "Zurück" und "Hinten" in einem Ansichtsmodell, das die beiden Ansichtsmodelle enthält, und lassen Sie die Modelle für die Kindansicht nur einmal erstellen, wenn sie zuerst benötigt werden. Dann können Ihre Navigationstasten bestimmen, welche Ansichtsmodelle aktuell sind und abhängig von der Logik aktiviert werden. In einem Wizard-Szenario sollten Sie Ihre untergeordneten Ansichtsmodelle auf einem Basisansichtsmodell basieren, das möglicherweise eine Eigenschaft oder eine Methode namens CanMoveNext() und CanMovePrior() aufweist. Intern kann dies wahr werden, wenn es fertig ist. Viel einfacher.

+0

Nein? Es ist kein Zauberer. Es ist One-Window-App mit Seitennavigation. Zum Beispiel ist FirstViewModel eine Liste von Elementen und SecondViewModel ist der Editor eines Elements –

Verwandte Themen