Xamarin.Forms Verständnisfrage ViewModel -- Activity

  • Xamarin.Android

Es gibt 2 Antworten in diesem Thema. Der letzte Beitrag () ist von seh.

    Xamarin.Forms Verständnisfrage ViewModel -- Activity

    Hallo,

    ich taste mich gerade etwas an Xamarin.Forms heran. Speziell geht es mir darum eine Android App zu entwickeln die ich aber später ohne erheblichen Mehraufwand auch für IOS oder den Desktop nutzen kann.
    Aktuell geht es mir aber erstmal nur um Android.

    Ich versuche gerade Google Sign In einzubauen. Dazu habe ich mir die paar NuGet Pakete geladen und schaue mir anhand der Beispiele an wie das funktioniert. Das klappt auch alles. Ich habe allerdings eine Verständnisfrage wie ich etwas bestimmtes hinbekommen kann.
    Es gibt ja das Hauptprojekt, welches von dem Android Projekt und dem IOS Projekt referenziert wird. Das Hauptprojekt bekommt ja nicht die Google Sign In libraries referenziert. Jetzt habe ich in meiner MainPage einfach einen Button der einen SignInCommand im SignInViewModel triggert.
    D.h. das ist mein aktuelles Setup:
    Das View:

    XML-Quellcode

    1. <?xml version="1.0" encoding="utf-8" ?>
    2. <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    4. xmlns:d="http://xamarin.com/schemas/2014/forms/design"
    5. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    6. mc:Ignorable="d"
    7. x:Class="MordhauTweakz.Views.AuthPage.SignInPage"
    8. Title="Sign In">
    9. <Grid Margin="10">
    10. <Button Command="{Binding SignInCommand}" Text="Google SignIn" />
    11. </Grid>
    12. </ContentPage>


    Das ViewModel dazu:

    C#-Quellcode

    1. public class SignInViewModel : BaseViewModel
    2. {
    3. public Command SignInCommand => new Command(SignIn_Click);
    4. public SignInViewModel()
    5. {
    6. }
    7. private void SignIn_Click(object obj)
    8. {
    9. MessagingCenter.Send<SignInViewModel>(this, "SignIn");
    10. }
    11. }


    Das Codebehind des Views:

    C#-Quellcode

    1. public partial class SignInPage : ContentPage
    2. {
    3. public SignInPage()
    4. {
    5. InitializeComponent();
    6. BindingContext = new SignInViewModel();
    7. }
    8. }


    Wenn ich das ganze Debugge und den Button auf meinem Gerät klicke, wird im ViewModel auch das SignIn_Click - "Event" gefeuert.
    Jetzt möchte ich von dort die SignIn Activity von Google öffnen lassen. Da das ViewModel ja in dem Hauptprojekt liegt und das Android Projekt nicht referenziert sondern anders herum kann ich ja nicht die Google API's nutzen. Ich muss jetzt also irgendwie der Android Activity mitteilen, dass sie die SignIn Activity launchen soll.
    Jetzt habe ich folgendes gefunden und dachte, dass ich das genau für sowas nutzen kann: docs.microsoft.com/de-de/xamar…amentals/messaging-center

    Im ViewModel in der OnClick mache ich also folgendes:

    C#-Quellcode

    1. private void SignIn_Click(object obj)
    2. {
    3. MessagingCenter.Send(this, "SignIn");
    4. }


    Und meine Android Activity OnCreate Methode sieht bisher so aus:

    C#-Quellcode

    1. protected override void OnCreate(Bundle savedInstanceState)
    2. {
    3. TabLayoutResource = Resource.Layout.Tabbar;
    4. ToolbarResource = Resource.Layout.Toolbar;
    5. base.OnCreate(savedInstanceState);
    6. GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DefaultSignIn)
    7. .RequestEmail()
    8. .Build();
    9. mGoogleApiClient = new GoogleApiClient.Builder(this)
    10. .EnableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
    11. .AddApi(Auth.GOOGLE_SIGN_IN_API, gso)
    12. .Build();
    13. MessagingCenter.Subscribe<string>(this, "SignIn", (param) =>
    14. {
    15. Device.BeginInvokeOnMainThread(() =>
    16. {
    17. var signInIntent = Auth.GoogleSignInApi.GetSignInIntent(mGoogleApiClient);
    18. StartActivityForResult(signInIntent, 9001);
    19. });
    20. });
    21. Xamarin.Essentials.Platform.Init(this, savedInstanceState);
    22. global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
    23. LoadApplication(new App());
    24. }


    Leider kommt das "Event" was ich subscribe nie an. Der Button Click wird ausgeführt. also das MessagingCenter.Send wird aufgerufen. Aber die Action die ich beim Subscribe angegeben habe wird nie ausgeführt... Warum nicht?
    Wenn ich das was in der Action vom Subscribe direkt ausführe in der OnCreate wird der SignIn Dialog direkt geöffnet. Das klappt also alles. Nur das "Event" wird nicht gefeuert!

    Weiß einer uum Rat?
    Nach etwas recherche, ist mir aufgefallen, dass dein Subscribe einen kleinen Fehler hat:
    MessagingCenter.Subscribe<string>(this, "SignIn", (param) =>
    Die Generische Angabe, die TSource lautet, bedeutet, nicht, dass du auf eine Nachricht vom Typ String wartest, sondern, dass du auf eine Nachricht von einem Objekt der Klasse string wartest. Deine Funktion bekommt dann das Objekt übergeben, das die Nachricht abgesendet hat. Das ist ähnlich wie mit einem Event, bei dem du ja oft diesen Parameter hast: object sender

    Dein Subscribe müsste also so aussehen:
    MessagingCenter.Subscribe<SignInViewModel>(this, "SignIn", (param) =>