Xamarin MvvmLight-Binding funktioniert nicht: Unterschied zwischen den Versionen

(Die Seite wurde neu angelegt: „==='''Symptom'''=== Sie benutzen in Ihrer Xamarin Android-App oder Ihrer Xamarin iOS-App das Binding mit MVVMLight. Es sollten dabei die Daten aus einem ViewMo…“)
 
 
(5 dazwischenliegende Versionen von 4 Benutzern werden nicht angezeigt)
Zeile 36: Zeile 36:
 
}
 
}
 
</pre><br />
 
</pre><br />
Dabei stellen Sie das Problem fest:<br /><br />
+
Dabei stellen Sie das Problem fest:<br />  
 
Binding funktioniert nicht zuverlässig, die Daten werden nicht immer korrekt in den Controls angezeigt. Manchmal dauert es sehr lange, bis die Daten in die Controls geladen werden. Manchmal werden je-doch auch trotz langer Wartezeit überhaupt keine Daten angezeigt.  
 
Binding funktioniert nicht zuverlässig, die Daten werden nicht immer korrekt in den Controls angezeigt. Manchmal dauert es sehr lange, bis die Daten in die Controls geladen werden. Manchmal werden je-doch auch trotz langer Wartezeit überhaupt keine Daten angezeigt.  
 +
 
==='''Ursache und Lösung'''===
 
==='''Ursache und Lösung'''===
 
Erstens, Sie sollten das mit MVVMLight erzeugte Binding beim Verlassen der Maske unbedingt wieder abhängen. Sonst bleibt dieses an dem ViewModel hängen und ein erneutes Binding wird bei der Navigation nicht mehr korrekt funktionieren:
 
Erstens, Sie sollten das mit MVVMLight erzeugte Binding beim Verlassen der Maske unbedingt wieder abhängen. Sonst bleibt dieses an dem ViewModel hängen und ein erneutes Binding wird bei der Navigation nicht mehr korrekt funktionieren:
Zeile 49: Zeile 50:
 
Was passiert, wenn Sie ein Binding in OnCreate/OnDestroy (Xamarin Android) bzw. in ViewDid-Load/ViewDidUnLoad (Xamarin iOS) erzeugen und abhängen? <br /><br />
 
Was passiert, wenn Sie ein Binding in OnCreate/OnDestroy (Xamarin Android) bzw. in ViewDid-Load/ViewDidUnLoad (Xamarin iOS) erzeugen und abhängen? <br /><br />
 
Dies erklären wir am Beispiel des Lifecycles einer Android-Activity:
 
Dies erklären wir am Beispiel des Lifecycles einer Android-Activity:
OnDestroy wird nur dann aufgerufen, wenn MeinActivity1 durch Klick auf den Navigationsbutton <BACK> verlassen wird. Wenn MeinActivity1 lediglich durch Aufruf einer weiteren MeinActivity2 verlassen wird, wird OnDestroy nicht aufgerufen. D.h. das Binding bleibt an Ihrem ViewModel hängen.  
+
OnDestroy wird nur dann aufgerufen, wenn MeinActivity1 durch Klick auf den Navigationsbutton <BACK> verlassen wird. Wenn MeinActivity1 lediglich durch Aufruf einer weiteren MeinActivity2 verlassen wird, wird OnDestroy nicht aufgerufen. D.h. das Binding bleibt an Ihrem ViewModel hängen.<br />
Folge: Wenn Sie dann zum MeinActivity1 nochmals neu mit  NavigationService.NavigateTo(MeinActivity1Key)  navigieren, wird in OnCreate das Binding nochmals erzeugt.  
+
<br />
Und dann kommt es ärgerlicherweise zu Kollisionen.<br /><br />
+
Folge: Wenn Sie dann zum MeinActivity1 nochmals neu mit  NavigationService.NavigateTo(MeinActivity1Key)  navigieren, wird in OnCreate das Binding nochmals erzeugt. Und dann kommt es ärgerlicherweise zu Kollisionen.<br /><br />
 
Workaround (nicht optimal, aber funktionierend): <br /><br />
 
Workaround (nicht optimal, aber funktionierend): <br /><br />
 
Xamarin Android:
 
Xamarin Android:
Zeile 60: Zeile 61:
 
</pre>
 
</pre>
 
==='''Weitere Informationen'''===
 
==='''Weitere Informationen'''===
https://mittelstand.max-it.de/Individualloesungen/App-Entwicklung/Xamarin<br /><br />
+
Mehr Informationen zu unseren Softwarelösungen und Services finden Sie auf<br />
 +
[https://www.max-it.de/techcorner/Xamarin_MvvmLight www.max-it.de/Softwarelösungen]
 +
 
 
==='''Links und Quellen'''===
 
==='''Links und Quellen'''===
http://developer.xamarin.com/guides/android/application_fundamentals/activity_lifecycle/#Activity_Lifecycle_Methods<br />
+
[http://developer.xamarin.com/guides/android/application_fundamentals/activity_lifecycle/#Activity_Lifecycle_Methods www.developer.xamarin.com/guides/android/application_fundamentals/activity_lifecycle/#Activity_Lifecycle_Methods]<br />
http://developer.xamarin.com/guides/android/application_fundamentals/activity_lifecycle/saving_state_walkthrough/<br /><br />
+
[http://developer.xamarin.com/guides/android/application_fundamentals/activity_lifecycle/saving_state_walkthrough/ www.developer.xamarin.com/guides/android/application_fundamentals/activity_lifecycle/saving_state_walkthrough]<br /><br />
 +
 
 +
=== '''Kontakt''' ===
 +
Wenn Sie Fragen oder Anmerkungen zu diesem Artikel haben, melden Sie sich bitte bei uns:<br />
 +
[http://mailto:techcorner@max-it.de techcorner@max-it.de].<br />
 +
 
 +
'''Über m.a.x. Informationstechnologie AG:''' <br />
 +
Als etabliertes Münchner Systemhaus zeichnen wir uns seit 1989 als verlässlicher IT-Partner mittelständischer und großer Unternehmen aus. Unser Portfolio reicht von IT- Services über individuelle Softwareentwicklung bis hin zur ERP-Beratung.
  
==='''Kontakt'''===
 
Wenn Sie Fragen oder Anmerkungen zu diesem Artikel haben, melden Sie sich bitte bei uns: mailto:techCorner@max-it.de. <br /><br />
 
 
==='''Tags'''===
 
==='''Tags'''===
 
Xamarin, android, ios, binding, mvvmlight, app
 
Xamarin, android, ios, binding, mvvmlight, app
  
 
[[Kategorie:Softwareentwicklung]]
 
[[Kategorie:Softwareentwicklung]]

Aktuelle Version vom 14. Mai 2020, 13:44 Uhr

Symptom

Sie benutzen in Ihrer Xamarin Android-App oder Ihrer Xamarin iOS-App das Binding mit MVVMLight. Es sollten dabei die Daten aus einem ViewModel an die Controls gebunden werden, z.B. an eine Liste oder an einzelne Labels. Die Bindings setzen Sie dabei in OnCreate (Android) bzw. in ViewDidLoad (iOS):

Android:

 public class MeinActivity1 : ActivityBase
{ 
      private Binding<ArtikelDetails, ArtikelDetails> _meinBinding;
       
      protected override void OnCreate(Bundle bundle)
      {
            base.OnCreate(bundle);
	
            _meinBinding = 
            this.SetBinding(() => MeinViewModel.ArtikelDetailsObjekt).WhenSourceChanges(() =>
            {
                 SetArtikelData();
            }
      }
}


iOS:

 public class MeinViewController1: ControllerBase
{ 
      private Binding<ArtikelDetails, ArtikelDetails> _meinBinding;
       
      public override void ViewDidLoad()
      {
            base.ViewDidLoad();
	
            _meinBinding = 
            this.SetBinding(() => MeinViewModel.ArtikelDetailsObjekt).WhenSourceChanges(() =>
            {
                 SetArtikelData();
            }
      }
}


Dabei stellen Sie das Problem fest:
Binding funktioniert nicht zuverlässig, die Daten werden nicht immer korrekt in den Controls angezeigt. Manchmal dauert es sehr lange, bis die Daten in die Controls geladen werden. Manchmal werden je-doch auch trotz langer Wartezeit überhaupt keine Daten angezeigt.

Ursache und Lösung

Erstens, Sie sollten das mit MVVMLight erzeugte Binding beim Verlassen der Maske unbedingt wieder abhängen. Sonst bleibt dieses an dem ViewModel hängen und ein erneutes Binding wird bei der Navigation nicht mehr korrekt funktionieren:

 if (_meinBinding != null)
            {
                _meinBinding.Detach();
                _meinBinding = null;
            }

Zweitens, es ist wichtig, den Lebenszyklus (Lifecycle) einer Activity bzw. eines ViewControllers genauer zu analysieren und Bindings zum jeweils richtigen Zeitpunkt zu behandeln.

Was passiert, wenn Sie ein Binding in OnCreate/OnDestroy (Xamarin Android) bzw. in ViewDid-Load/ViewDidUnLoad (Xamarin iOS) erzeugen und abhängen?

Dies erklären wir am Beispiel des Lifecycles einer Android-Activity: OnDestroy wird nur dann aufgerufen, wenn MeinActivity1 durch Klick auf den Navigationsbutton <BACK> verlassen wird. Wenn MeinActivity1 lediglich durch Aufruf einer weiteren MeinActivity2 verlassen wird, wird OnDestroy nicht aufgerufen. D.h. das Binding bleibt an Ihrem ViewModel hängen.

Folge: Wenn Sie dann zum MeinActivity1 nochmals neu mit NavigationService.NavigateTo(MeinActivity1Key) navigieren, wird in OnCreate das Binding nochmals erzeugt. Und dann kommt es ärgerlicherweise zu Kollisionen.

Workaround (nicht optimal, aber funktionierend):

Xamarin Android:

Binding in OnStart erzeugen, und dann in OnStop ablösen (detach).

Xamarin iOS:

Binding in ViewWillAppear erzeugen, und dann in ViewDidDisappear ablösen (detach).

Weitere Informationen

Mehr Informationen zu unseren Softwarelösungen und Services finden Sie auf
www.max-it.de/Softwarelösungen

Links und Quellen

www.developer.xamarin.com/guides/android/application_fundamentals/activity_lifecycle/#Activity_Lifecycle_Methods
www.developer.xamarin.com/guides/android/application_fundamentals/activity_lifecycle/saving_state_walkthrough

Kontakt

Wenn Sie Fragen oder Anmerkungen zu diesem Artikel haben, melden Sie sich bitte bei uns:
techcorner@max-it.de.

Über m.a.x. Informationstechnologie AG:
Als etabliertes Münchner Systemhaus zeichnen wir uns seit 1989 als verlässlicher IT-Partner mittelständischer und großer Unternehmen aus. Unser Portfolio reicht von IT- Services über individuelle Softwareentwicklung bis hin zur ERP-Beratung.

Tags

Xamarin, android, ios, binding, mvvmlight, app