Xamarin Forms Experts Sample App Walkthrough

In diesem Xamarin Forms Beispiel kann sich jeder zum Xamarin Experten krönen. Auf der mit AngularJS erstellten und auf Azure gehosteten Website http://xamarindevs.azurewebsites.net/app/app.html werden die Experten angezeigt.

Im Teil 1 unseres Hands On Workshops, wird eine Xamarin Forms MVVM App erstellt um die Daten hochzuladen. Dazu dient eine Rest API auf Basis der ASP.NET Web Api.

Mit Visual Studio 2015 ein Cross Plattform Projekt anlegen- Xamarin.Forms Shared oder Portable Class Library.

Im Shared Projekt eine Datei hinzufügen- Cross Platform – Forms Xaml Page, mit dem Namen Page1

image

Diese Seite wird später ein einfaches Userinterface beinhalten um einen neuen Xamarin Experten anzulegen.

image

Achtung: Xamarin.Forms im Droid Projekt nur auf Version 2.1.0.6529 updaten. Alles andere ist nicht erfolgreich getestet.

image

Um diese Seite als Startseite in der App zu bekommen wird in der Datei app.cs, diese instanziert und der Mainpage zugewiesen

   1:  public App ()
   2:          {
   3:              // The root page of your application
   4:              MainPage = new Page1();

Als nächstes wird im shared Projekt eine Modelklasse mit dem Namen experten.cs erzeugt.

Die Definiton der Eigenschaften kann aus dem REST Service http://xamarindevs.azurewebsites.net/api/experten ausgelesen werden.

Visual Studio enthält eine Funktion “Paste Json as Classes” um die Klasse erzeugen zu lassen. Alternativ gibt es auch Online Dienste die diese Funktion anbieten. Im folgenden Code kommen Dataannotations zum Einsatz um die Gültigkeit von Daten zu validieren.  Ein Required Attribut erfordert so einen Wert im Feld Alias.

In jedem Geräte spezifischen Projekt muss das Assembly System.ComponentModel.Dataannotations erst aktiviert werden. Dies geschieht in den Projekt Verweisen/Referenzen.

image

Das Beispiel funktioniert auch ohne diese Metadaten.

   1:     public class experte
   2:      {
   3:   
   4:          public int Id { get; set; }
   5:   
   6:          [Required]
   7:          [StringLength(50)]
   8:          public string Alias { get; set; }
   9:   
  10:          public int Pin { get; set; }
  11:   
  12:          [StringLength(50)]
  13:          public string Email { get; set; }
  14:   
  15:          [StringLength(50)]
  16:          public string Name { get; set; }
  17:   
  18:          [StringLength(50)]
  19:          public string Ort { get; set; }
  20:   
  21:          [StringLength(512)]
  22:          public string SkillText { get; set; }
  23:   
  24:          public bool Open { get; set; }
  25:   
  26:          public bool Hidden { get; set; }
  27:   
  28:          [StringLength(50)]
  29:          public string Url { get; set; }
  30:   
  31:         // [Column(TypeName = "date")]
  32:          public DateTime Datum { get; set; }
  33:   
  34:      }

 

In einem MVVM Projekt wird auch ein Viewmodel benötigt. Dazu wird eine Klasse expertenVM.cs erzeugt. Diese hält als Property den Neuen Experten= neuExperte, der im Konstruktor zugewiesen wird. Um Datenbindung im XAML Code nutzen zu können müssen immer offentliche Eigenschaften/Propertys verwendet werden. So auch für den Button Click vom Typ ICommand. Anders als man das im WPF Code meist macht, wird auf eine RelayCommand Abstraktion verzichtet und direkt das Delegate Event im Konstruktor zugwiesen. Dazu wird die Xamarin eigene Command Klasse genutzt, die damit das Relaycommand überflüssig macht.

Um aus einem .NET Objekt einen JSON String zu erstellen wird per Nuget die Library Newtonsoft.Json in das Geräte Projekt (also zb Droid) geladen.

image

Für System.net.http wird der Verweis hinzugefügt.

image

 

   1:   class ExpertenVM
   2:  {
   3:          public ExpertenVM()
   4:          {
   5:              neuExperte = new experte();
   6:              this.addExpert = new Command(_addExpert);
   7:   
   8:          }
   9:   
  10:   
  11:          private async void _addExpert(object obj)
  12:          {
  13:              neuExperte.Datum = DateTime.Now;
  14:              var uri = new Uri("http://xamarindevs.azurewebsites.net/api/experten/");
  15:              using (var client = new HttpClient())
  16:              {
  17:                  var json = JsonConvert.SerializeObject(neuExperte);
  18:                  var content = new StringContent(json, Encoding.UTF8, "application/json");
  19:                  HttpResponseMessage response = null;
  20:                  response = await client.PostAsync(uri, content);
  21:   
  22:                  if (response.IsSuccessStatusCode)
  23:                  {
  24:                       await App.Current.MainPage.DisplayAlert("Experte","angelegt" , "OK");
  25:                 
  26:                  }
  27:              }
  28:          }
  29:   
  30:          public ICommand addExpert { get; set; }
  31:          public experte neuExperte { get; set; }
  32:   
  33:      }
  34:  }

Im Codebehind der Datei page1.xaml.cs wird das Viewmodel instanziert und dem Bindingcontext zugewiesen.

   1:   public Page1()
   2:          {
   3:              InitializeComponent();
   4:              var vm = new ExpertenVM();
   5:              BindingContext = vm;

Achtung in WPF lautet die entsprechende Eigenschaft DataContext und wird meist deklarativ im XAML Code erstelllt.

Nun wird im XAML Code der Xamarin Forms Code geschrieben um das Userinterface zu deklarieren. Deutlich zu erkennen ist der Unterschied zu WPF (Stackpanel, Textbox). Die Binding Syntax an die Eigenschaften des Viewmodels sind ident.

   1:    <StackLayout VerticalOptions="FillAndExpand" 
   2:                        HorizontalOptions="FillAndExpand"
   3:                        Orientation="Vertical"
   4:                        Spacing="15">
   5:      <Entry x:Name="LastName"
   6:           Placeholder="Name"
   7:           HorizontalOptions="FillAndExpand"
   8:           VerticalOptions="End"
   9:             Text="{Binding neuExperte.Name}"
  10:             />
  11:      <Entry x:Name="Alias"
  12:            Placeholder="Alias"
  13:            HorizontalOptions="FillAndExpand"
  14:            VerticalOptions="End"
  15:             Text="{Binding neuExperte.Alias}"/>
  16:      <Entry x:Name="email" Keyboard="Email"
  17:            Placeholder="email"
  18:            HorizontalOptions="FillAndExpand"
  19:            VerticalOptions="End" 
  20:             Text="{Binding neuExperte.Email}"/>
  21:      <Entry x:Name="pin" Keyboard="Numeric"
  22:        Placeholder="Pin"
  23:        HorizontalOptions="FillAndExpand"
  24:        VerticalOptions="End" 
  25:             Text="{Binding neuExperte.Pin}"/>
  26:   
  27:      <Button Text="anlegen" Command="{Binding addExpert}" ></Button>
  28:   
  29:    </StackLayout>

 

Das Beispiel im Android Emulator oder am physikalischen Device ausführen.

Achtung: andere Projekte wie IOS können aus der Solution gelöscht werden, da ohnehin kein Mac Computer zu kompilieren zur Verfügung steht. Für diesen Walkthrough reicht das Shared Projekt und das Droid Projekt. Sollten Sie eine Windows 10 Maschine nutzen auch das UWP (Universal Windows Platform) Projekt behalten.

image

Zeile 24 im Viewmodel App.Current.MainPage.DisplayAlert bricht mit der strikten Trennung von UI und Logik. Da Xamarin das in einer Art Service Provider wegkapselt von der realen Implementierung könnte man damit leben. Um aus dem Viewmodel das UI zu Aktionen zu bewegen, ist eigentlich Binding gedacht. Ein zb verdecktes Panel, dessen Show Eigenschaft an eine Eigenschaft des Viewmodels gebunden wird. Alternativ lässt sich über Events und Actions nachdenken. So eine Eigenschaft wird dem Viewmodell hinzugefügt.

   1:     public Action CallBackAction { get; set; }

Im Konstruktor wird diese CallBackAction mit einem Dummy Event befüllt.

   1:    public ExpertenVM()
   2:          {
   3:              neuExperte = new experte();
   4:            
   5:              this.addExpert = new Command(_addExpert);
   6:            
   7:              CallBackAction = () => { };

Im Konstruktor de Page wird das Avent des Viewmodels abonniert und per Funktion beliebige UI Aktionen ausgeführt.

   1:   public Page1()
   2:          {
   3:              InitializeComponent();
   4:              var vm = new ExpertenVM();
   5:              vm.CallBackAction = () => DisplayAlert("Experte", "angelegt", "Ok");
   6:           

Dem Benutzer der App wird nun gezeigt, das der neue Experte erfolgreich an den REST Service übermittelt wurde. Allerdings bleibt das Formular mit den alten Daten gefüllt. Der natürliche Reflex überschriebt einfach gleichzeitig mit dem Popup das neuExperte Objekt.

   1:   if (response.IsSuccessStatusCode)
   2:                  {
   3:                      neuExperte = new experte();

Allerdings wird das UserInterface damit nicht über diese Änderung informiert. Es benötigt ein Event Notification System, was mit dem Interface INotifyPropertyChanged dem Viewmodel hinzugefügt wird.

   1:   class ExpertenVM:INotifyPropertyChanged
   2:      {

Es wird der Namensraum System.Componentmodel benötigt und die implementierung des Interface Events. Visual Studio hilft über STRG +PUNKT

   1:   public event PropertyChangedEventHandler PropertyChanged;

Sozusagen Branchenüblich kapselt man dieses Event in eine Funktion, mit Hilfe man das UI dann über Änderungen informiert. Die Implementierung per Callermembername erlaubt es in Settern den üblicherweise als String übergebenen Propertynamen einfach weg zu lassen. Name wird dann sozusagen automatisch gefüllt.

   1:   protected void OnPropertyChanged([CallerMemberName] string name = null)
   2:          {
   3:              PropertyChangedEventHandler handler = PropertyChanged;
   4:              if (handler != null)
   5:              {
   6:                  handler(this, new PropertyChangedEventArgs(name));
   7:              }
   8:          }

Allerdings kann der Aufruf auch außerhalb eines Properties erfolgen. Das Beispiel leert das Formular im Erfolgsfall und feuert ans UI das Event, das die Bindungen bezüglich neuExperte zu aktualisieren sind.

   1:   if (response.IsSuccessStatusCode)
   2:                  {
   3:                      neuExperte = new experte();
   4:                      OnPropertyChanged("neuExperte");
   5:                      CallBackAction(); // entkoppelt
   6:                 

Letztendlich noch die Website zur Anzeige

image

Im Teil 2 werden die Details geändert und ein Foto hinzugefügt.

Kommentare sind geschlossen