Juni 2015

Volume 30 Number 06

Dieser Artikel wurde maschinell übersetzt.

Xamarin - Implementierung und Verwendung von Datenbindung in Xamarin

By Laurent Bugnion**

Binden von Daten ist ein beliebtes Konzept programmieren Sie heutzutage besonders für Clientanwendungen. In diesem Artikel werde ich erläutern, welche Bindung ist und wie diese Technologien verwendet werden, die es direkt, wie z. B. Windows XAML unterstützen. Nachdem die Grundprinzipien von Datenbindungsfunktionen Observable-Eigenschaften und wie diese Technologien verwendet werden können, die Binden von Daten im"Paket" nicht unterstützen eingegangen, zeige ich wie die Unterstützung der Bindung die Xamarin.Android und Xamarin.iOS mit dem MVVM Light Toolkit hinzugefügt werden kann (mvvmlight.net). Dieses einfache Toolkit ist das beliebteste Model-View-ViewModel (MVVM)-Framework für Plattformen wie Windows Presentation Foundation (WPF), Silverlight, Windows Phone, Windows Store, Xamarin.Android, Xamarin.iOS, Xamarin.Forms und vieles mehr.

Schluss werde ich mit einer Erläuterung der Datenbindung in Xamarin.Forms, die neueste Erweiterung von der Xamarin-Frameworks, von der Benutzeroberfläche in XAML einmal zu erstellen und wieder Android, iOS und Windows Phone ausführen können.

Was ist Data Binding?

Binden von Daten versteht man das Verbinden der Benutzeroberfläche und der Geschäftslogik. Durch Datenbindung, werden zwei verbundene Eigenschaften synchronisiert bleiben. Dies ist nützlich, wenn Sie einen Wert für ein Objekt (das Datenmodell, häufig als "ViewModel" bezeichnet) ändern, auch automatisch die entsprechende Eigenschaft in der Benutzeroberfläche aktualisiert wird. Auf ähnliche Weise wird im Fall von "bidirektionales" Datenbindung Änderung eines Werts in der Benutzeroberfläche das ViewModel aktualisieren. Binden von Daten wurde für Clientanwendungen für einen bestimmten Zeitraum verfügbar, noch bevor WPF und alle anderen XAML-basierten Technologien eingeführt wurden. In ASP.NET Web Forms Steuerelemente Daten beispielsweise, z. B. Listbox Daten – eine Auflistung von Elementen gebunden werden kann, die auf dem Bildschirm dargestellt werden muss. Um "das Datenelement in einer visuellen Darstellung zu übersetzen", wird eine Elementvorlage in der Regel definiert. Dies ist ein kleines Snippet HTML-Code, in dem einige der Steuerelemente, die Werte der Elementeigenschaften anzeigen.

In XAML wurde das Konzept erweitert wird und sagen, dass jeder Entwickler XAML-Bindung in einem Umfang größer oder kleiner verwendet. Während es verlockend sein kann, behandeln die meisten des Datenmodells im Quellcode direkt (insbesondere für Entwickler von herkömmlichen Technologien, die diesen Mechanismus nicht unterstützen), einmal die Leistungsfähigkeit der Bindung modelliert wurde es ist nahezu unmöglich, den mühsamer Prozess des Schreibens von Daten Change Management im Quellcode zurückzukehren.

Mehr als nur Datensteuerelemente

XAML-Bindung ist viel mehr als "nur" Datensteuerelemente. Sie können nahezu jede Eigenschaft eines Objekts an eine andere Eigenschaft binden. (Bedenken Sie, dass nur eine besondere Art von Eigenschaft mit dem Namen einer Abhängigkeitseigenschaft [DP] Ziel Datenbindungsfunktionen sein kann. DPs vorhanden nicht, Android und iOS, weshalb die verfügbaren Datenbindungsausdrücke Frameworks einige Abhilfen verwenden.)

Binden von Daten ist ein wiederhergestellter Interesse in der Welt des Webs mit der Einführung von Frameworks wie KnockoutJS und AngularJS, mit Datenbindungsausdrücke Erweiterungen der JavaScript-Code im Hintergrund ausgeführt wird. Diese Datenbindungsausdrücke Frameworks sind stark von XAML-Frameworks inspiriert, und es ist interessant, finden in einem großen Publikum Übernahme der Prinzipien (z. B. das MVVM-Muster), die durch die XAML-Communitys entwickelt wurden.

Ein deklarativer Prozess

Markup-Technologien, wie XAML und HTML deklarative aufgerufen werden, da sie Sie für die Benutzeroberfläche "Ihre Absicht deklarieren" ermöglichen. Dies ist in der Regel zu einem anderen Zeitpunkt als der Implementierung fertig, und manchmal sogar von einem anderen Team. Beispielsweise werden in XAML-Technologien, die Benutzeroberfläche für das XAML verantwortlichen Entwickler "Integratoren" oder manchmal "Interaktion Entwickler" oder sogar die barbaric "Devsigner." aufgerufen Diese Funktion impliziert ein gutes Verständnis der Vision des Designers, für die Anwendung, und die, obwohl Integratoren häufig Entwickler sind, zwischen zwei Stühlen zu sitzen und haben eine kreative Verantwortung bei der Anwendungsentwicklung.

Dank der Datenbindung kann sogar auf kleine Entwicklungsteams, um den Prozess der Erstellung der Benutzeroberfläche stark unterscheiden. Wenn ich auf kleine apps arbeiten, wo ich der einzige Entwickler bin, möchte ich sagen, dass ich während des Entwicklungsprozesses Hüten wechseln. Wenn ich Code z. B. das Datenmodell Datendienste und so weiter bearbeiten, Abnutzung ich meine Entwickler Hat. Beim Wechseln zum Erstellen der Benutzeroberfläche ändern ich dann meinen Hut Integrator.

Diese Trennung von Rollen reflektiert die Trennung von Bereichen, die häufig in der modernen Softwareentwicklung geeignet ist. Binden von Daten durch diese Trennung absolut verlangen nicht, ist eine sehr bequeme Herangehensweise, die Sie in der richtigen Denkweise abrufen kann.

Gibt es in Xamarin Binden von Daten?

Wie können in Windows Phone, Xamarin.Android und Xamarin.iOS die Benutzeroberfläche direkt im Quellcode erstellt werden, sondern bieten auch mithilfe einer XML-Datei mit deklarativem Markup innovativen Ansatzes. In Android ist dies eine AXML-Datei. In iOS ist eine bequeme Herangehensweise, die Storyboard-Dateien verwenden. Dies ist ähnlich wie wir in Windows Phone mit XAML. Beachten Sie, dass diese deklarativen Markup-Dateien nicht für Xamarin spezifisch sind. Sie sind auch in herkömmlichen Android und iOS-Entwicklung verwendet werden.

Während praktisch (insbesondere deshalb, weil sie arbeiten mit einem visuellen Designertool wie in Xcode oder in Visual Studio bereitgestellten ermöglichen), Dateien mit deklarative Markup Android und iOS sind weniger leistungsfähig als XAML. Es fehlen insbesondere was XAML-Markuperweiterung aufruft. Solche Ausdrücke werden in geschweifte Klammern ({}) eingeschlossen. Es gibt diverse dieser Erweiterungen, z. B. zum Zugriff auf Ressourcen in einem XAML-Dokument oder zum Erstellen einer Datenbindung befinden, wie im folgenden Codeausschnitt gezeigt:

<Button Content="{Binding ButtonContent}"
        Command="{Binding ExecuteCommand}"
        CommandParameter="{Binding IsChecked, ElementName=LockCheckBox}" />

Dieses Markup, einer Sicht gehört, besagt, dass ein Schaltflächen-Steuerelement verfügt über seine Eigenschaft Inhalt an eine Quelleigenschaft mit dem Namen ButtonContent gebunden und die Command-Eigenschaft, um eine Quelleigenschaft ExecuteCommand aufgerufen gebunden ist. Diese Eigenschaften finden Sie unter Objekt als die Standarddaten oder Bindungskontext für die Schaltfläche Eltern (häufig die Seite als Ganzes) fungiert in der Regel das ViewModel-Objekt. Allerdings können Sie den Bindungskontext auf jeder Ebene festlegen, die Sie benötigen. Die dritte Zeile des Markups laut z. B. explizit die Schaltfläche CommandParameter an die IsChecked-Eigenschaft eines anderen Elements auf der Seite gebunden ist, dessen Name LockCheckBox ist.

Leider ist das Konzept der Bindung existiert nicht systemintern in Android oder iOS damit im Rest dieses Artikels, ich Ihnen zeige wie in Xamarin Bindung für diese beiden Plattformen implementiert werden kann, und dann wie eine Implementierung von MVVM Light Toolkit bietet können Sie den Prozess zu vereinfachen. Xamarin bietet darüber hinaus auch eine Erweiterung mit dem Namen Xamarin.Forms, die eine XAML-Markup-Sprache ähnlich Windows für die Benutzeroberfläche verwendet. Xamarin.Forms unterstützt Bindungsdeklaration im Markup direkt, ohne externe Frameworks.

Implementieren von Data Binding in Android und iOS

Ich werde eine kleine Anwendung erstellen, die eine Verbindung mit einem einfachen Datendienst und gibt eine Liste von Blumen, jeweils einen Namen und eine Beschreibung. Sie finden diese Anwendung mit dem Namen XamDataBinding,galasoft.ch/s/xambinding. Aus Gründen der Einfachheit, ich werde konzentrieren Sie sich auf nur eine Seite angezeigt, dieAbbildung 1. Auf dieser Seite, Android, iOS und Windows Phone implementiert hat die folgenden Funktionen:

  • Eine Liste von Blumen. Die Liste sollte im Idealfall selbst aktualisieren, wenn die zugrunde liegende ändert Datenquelle.
  • Eine Schaltfläche zum Aktualisieren der Liste.
  • Text, Datum und Uhrzeit der letzten Aktualisierung angezeigt.
  • Ein Kontrollkästchen "Lock" oder Switch. Der Zweck dieses Elements nicht sehr sinnvoll, in einem Produktionsszenario jedoch für die Demo, stellen Sie sich vor, dass dies "die Schaltfläche" Aktualisieren "Sperren", wenn diese Option aktiviert ist.

Sample Application in Android, iOS and Windows Phone
Abbildung 1 Beispielanwendung in Android, iOS und Windows Phone

Das MVVM-Muster stützt sich auf ein paar einfachen Prinzipien:

  • Observable-Objekte implementieren die INotifyPropertyChanged-Schnittstelle. Diese Schnittstelle .NET macht das PropertyChanged-Ereignis ausgelöst werden soll, wenn eine überwachbare Eigenschaft geändert wird.
  • Listen, die im Verlauf einer Anwendung ändern können, sollten in ObservableCollection < T >-Instanzen gespeichert werden.
  • Eine solche Liste löst das CollectionChanged-Ereignis bei Änderung des Inhalts (hinzufügen, entfernen oder eine andere Sortierreihenfolge).
  • Einige Objekte verfügbar machen, Funktionalität in einer Eigenschaft, die die ICommand-Schnittstelle implementieren. Diese Schnittstelle definiert eine Execute-Methode und eine CanExecute-Methode. Letztere Gibt WAHR oder falsch, je nachdem, ob die Execute-Methode ausgeführt werden kann. Darüber hinaus gibt ICommand ein CanExecuteChanged-Ereignis. Dieses Ereignis muss ausgelöst werden, wenn der Rückgabewert von der CanExecute-Methode ändert dies beeinflussen den Status der gebundenen UI-Steuerelemente.

In der MVVM Light Toolkit werden diese Schnittstellen von konkreten Klassen wie die ObservableObject ViewModelBase (INotifyPropertyChanged) und die RelayCommand (ICommand) implementiert. Im Beispiel XamDataBinding werden die Ebenen Modell und ViewModel MVVM Light Toolkit integriert und in eine portable Klassenbibliothek namens XamDataBinding.Data gespeichert. Diese Bibliothek kann zwischen Xamarin und Windows freigegeben werden.

In MVVM ist jede Ansicht "durch ein" ViewModel "driven". In Windows und Windows Phone ist "ViewModel" in der Regel als "DataContext", verwendet eine Eigenschaft der Ansicht (Seite, Fenster, UserControl usw.). Dies ist eine bequeme Möglichkeit zum Binden von Daten zu verwenden, ohne dass die Quelle der Bindung an. Android und iOS gibt es kein Konzept von DataContext. Stattdessen deklarieren in der Ansicht "ViewModel" und sofort verwenden. Eine kleine Anwendung wie im Beispiel XamDataBinding kann "ViewModel" direkt in der Ansicht (der Aktivität in der MainViewController in iOS, Android und in Windows Phone MainPage) erstellt werden:

private MainViewModel _vm;
public MainViewModel Vm
{
  get
  {
    return _vm ?? (_vm = new MainViewModel());
  }
}

Bindung und Befehle ohne ein Framework implementieren

Um zu vermeiden, dasselbe immer wieder wiederholen, werde ich hier auf Android-Anwendung des Beispiels XamDataBinding konzentrieren. Genau dieselben Konzepte gelten jedoch für die iOS-Anwendung. Da keines dieser Plattformen Bindung unterstützt, implementiere ich Bindung und Befehle manuell:

  • Ich werde die MainViewModel PropertyChanged-Ereignis in der Ansicht behandeln, den Namen der geänderten Eigenschaft zu überprüfen und aktualisieren die Ansicht entsprechend.
  • Einige Bindungen in zwei Richtungen (bidirektionale Bindung) wechseln. Wenn ein Kontrollkästchen geklickt wird, muss die entsprechende boolesche Eigenschaft in "MainViewModel" z. B. aktualisiert werden. Ohne ein Framework Bindung muss ich die Checkbox-Ereignis abonnieren und aktualisieren Sie das ViewModel-Eigenschaft manuell aus der Sicht.
  • Mit der Aktualisierungsschaltfläche muss der RefreshCommand-Befehl in "MainViewModel" ausführen. Ohne ein Framework Befehlsinfrastruktur muss dies ebenfalls manuell verarbeitet werden. Kann ich der Schaltfläche behandeln Click-Ereignis, und rufen Sie die Execute Methode direkt aus der Ansicht.
  • Schließlich weiß ich, dass der Befehl deaktivieren kann, das Steuerelement an dem es gebunden ist. Ohne ein Framework Befehlsinfrastruktur muss ich in diesem Fall den Befehl CanExecuteChanged Ereignis zu abonnieren. Wenn dieses Ereignis ausgelöst wird, kann ich rufen die CanExecute Methode und, je nach dem zurückgegebenen Wert, aktivieren oder deaktivieren das Steuerelement.

Keiner dieser Schritte ist sehr komplex, jedoch aufwendig und sich wiederholende der gesamte Prozess sein. In der Praxis ist es einfacher, ein Framework binden und Befehle, z. B. ein, die von den MVVM Light Toolkit Angeboten zu verwenden.

Mithilfe von MVVM Light Datenbindungsausdrücke Framework

Die vorherigen Beispiele funktionieren, sind aber schreiben, da Sie verschiedene Ereignisse zu behandeln und stellen Sie sich alle möglichen Szenarien lästig. Sie sind auch schwieriger zu verwalten und zu verstehen, insbesondere dann, wenn viele Elemente der Benutzeroberfläche zu behandeln.

Das einfache-Datenbindungs-Framework in der MVVM Light Toolkit ermöglicht hingegen die Beziehung zwischen der Elemente der Benutzeroberfläche und den Code als auch die Benutzeroberflächenelemente und Befehle erstellen. Dank dieses Framework Bindung kann ich Bindungen erstellen und Zuordnen von Befehlen in der Methode OnCreate SieheAbbildung 2.

Abbildung 2 – Erstellen von Bindungen und Befehle

_lastLoadedBinding = this.SetBinding(
  () => Vm.LastLoadedFormatted,
  () => LastLoadedText.Text);
_lockBinding = this.SetBinding(
  () => Vm.IsLocked,
  () => LockCheckBox.Checked,
  BindingMode.TwoWay);
_refreshCommandBinding = this.SetBinding(
  () => LockCheckBox.Checked);
RefreshButton.SetCommand("Click", Vm.RefreshCommand, _refreshCommandBinding);
FlowersList.Adapter = Vm.Flowers.GetAdapter(GetFlowerAdapter);

InAbbildung 2zuerst ich eine unidirektionale Bindung zwischen der MainViewModel-LastLoadedFormatted-Eigenschaft und die Text-Eigenschaft der TextView erstellen. Diese einzelne Codezeile übernimmt die permanente Beziehung zwischen diesen beiden Eigenschaften einrichten. Beachten Sie, dass die Erweiterungsmethode SetBinding-, die von den MVVM Light bereitgestellt wird. Diese Methode gibt die Bindungsinstanz, die erstellt wurde. Da das Binding-Objekt mit WeakReferences, um Speicherverluste zu vermeiden geschrieben wird, sollte dieser Bindung als privates Feld, um zu verhindern, dass die Bindung von erste automatisch getrennt gespeichert werden.

Die zweite Anweisung erstellt die bidirektionale Bindung zwischen der IsLocked-Eigenschaft von "MainViewModel" und die Checked-Eigenschaft der LockCheckBox. Beachten Sie, dass standardmäßig eine jede Bindung unidirektional ist, müssen Sie die TwoWay BindingMode in der SetBinding--Methode angeben.

Die dritte Anweisung erstellt eine besondere Art von Bindung mit nur einer Quelle und kein Ziel. Hier die Quelle ist die aktivierte Eigenschaft für die LockCheckBox. Ich verwende diese Bindung in der Methode SetCommand "MainViewModel" angewiesen, dass die LoadCommand erneut ausgewertet werden sollen, jedes Mal, wenn die LockCheckBox Checked-Eigenschaft ändert. In XAML würde ich eine Bindung auf die Schaltfläche CommandParameter erstellen. Hier eine ähnliche Konstrukt durch Erstellen der Bindung verwendet zuerst und anschließend diese Instanz der SetCommand-Methode übergeben.

Die vierte Anweisung setzt einen Befehl auf der RefreshButton. Obwohl ich das Click-Ereignis zu behandeln, konnte ich den Befehl für jedes Ereignis des ausgewählten Element der Benutzeroberfläche in der Tat betätigt. Der zweite Parameter der Methode SetCommand ist der Befehl, der abhängig sein muss. Schließlich wird der dritte Parameter ist optional und wird nur für Befehle, die einen Parameter erfordern benötigt. Wie bereits erwähnt, verwende ich hier die zuvor erstellte Bindung.

Festlegen der Liste

Es gibt ein ListView-Steuerelement in der Benutzeroberfläche. MVVM Light bietet eine sehr nützliche Erweiterungsmethode namens GetAdapter, die auf eine beliebige ObservableCollection oder alle IList verwendet werden kann. Es gibt einen Android-Adapter, der als "ListView" Adapter-Eigenschaft verwendet werden kann. Da der MainViewModel-Blumen-Eigenschaft eine ObservableCollection handelt, wird die Benutzeroberfläche Änderung die Auflistung automatisch aktualisiert:

FlowersList.Adapter = Vm.Flowers.GetAdapter(GetFlowerAdapter);

Die GetFlowerAdapter-Methode, die die GetAdapter-Methode übergeben wird, wird verwendet, um die Zeile anzuzeigen, die eine Blume darstellt. In diesem Beispiel kann ich alles einfacher mithilfe einer integrierten Zeile anzeigen, in dem das Bild und den Namen der Blume, als angezeigtAbbildung 3zeigt. Es wäre jedoch sehr einfach, zum Erstellen einer benutzerdefinierten Zeile-Ansicht mit mehr Details oder ein anderes Layout.

Wenn ich die Anwendung jetzt ausführen, sehen ich die Benutzeroberfläche im angezeigtenAbbildung 1. Sie können Folgendes versuchen:

  • Durch Klicken auf das Kontrollkästchen Sperre deaktiviert die Schaltfläche "Aktualisieren". Tritt auf, die Deaktivierung der RefreshCommand-Befehl und seine CanExecute-Methode. Überprüfen Sie die MainViewModel-Code, um herauszufinden, wie dies funktioniert. Beachten Sie, dass dieselbe Wirkung in XAML ausgeführt werden, wenn Sie in Windows Phone-Anwendung ausführen.
  • Wenn die Schaltfläche "Aktualisieren" aktiviert ist, lädt klicken sie auf die Liste der Blumen asynchron. Beachten Sie den Code, der auf den Webdienst in "MainViewModel" enthalten ist, und ist vollständig auf allen Plattformen unterstützt, die von diesem portable Klassenbibliothek wiederverwendet werden.
  • Nach dem Laden der Liste wird der Status der TextView "zuletzt geladenen" Informationen aktualisiert. Dies erfolgt ebenfalls über die Bindung erstellten.
  • IOS oder Windows Phone-Version der Anwendung ausgeführt werden dieselben Ergebnisse erstellt. In iOS werden die Bindungen in der MainViewController ViewDidLoad-Methode erstellt. In Windows Phone erstellt habe ich die Bindungen in "MainPage.xaml".

Abbildung 3: Erstellen einer benutzerdefinierten ListView-Zeile

private View GetFlowerAdapter(
  int position,
  FlowerViewModel flower,
  View convertView)
{
  if (convertView == null)
  {
    convertView = LayoutInflater.Inflate(
    Android.Resource.Layout.ActivityListItem, null);
  }
  var text = convertView.FindViewById<TextView>(Android.Resource.Id.Text1);
  text.Text = flower.Model.Name;
  var image = convertView.FindViewById<ImageView>(Android.Resource.Id.Icon);
  image.SetImageBitmap(GetImageBitmapFromUrl(flower.ImageUri.AbsoluteUri));
  return convertView;
}

Datenbindung in Xamarin.Forms

Im letzten Jahr veröffentlicht Xamarin das Forms-Framework ermöglicht die gleichzeitige Verwendung nicht nur Code, sondern auch die Benutzeroberfläche über alle unterstützten Plattformen. Dies ist ideal für die Erstellung einer Benutzeroberfläche schnell, um Code zu testen. z. B. während der Erstellung von Prototypen-Phase. Das Forms-Framework kann auch für Produktionscode, wie z. B. Line-of-Business-Anwendung verwendet werden, die auf mehreren Plattformen ausgeführt werden.

Im Gegensatz zu Xamarin.iOS und Xamarin.Android unterstützt Xamarin.Forms systemintern Binden von Daten an. Da es unterstützt außerdem XAML (obwohl es sich um eine andere Version als die in WPF, Windows Phone und Windows Store), Sie können die Datenbindung direkt im XAML-Markup schreiben. Dies bedeutet, dass Sie etwa Folgendes schreiben können:

<Label Text="{Binding LastLoadedFormatted}"
       VerticalOptions="Center"
       HorizontalOptions="Center" />

Im Beispiel enthalten kann sogar noch durch Xamarin.Forms verwenden und Wiederverwenden von der Benutzeroberfläche auf jeder Plattform vereinfacht werden. Natürlich kann Xamarin.Forms für Applikationen, in dem zusätzliche mit der UX geachtet werden muss, nicht die beste Lösung sein. Aber für eine Vielzahl von apps, Formulare werden vereinfacht UI-Entwicklung erheblich, so mehr Zeit für andere Aufgaben, wie z. B. die Verbesserung der Leistung der Anwendung und Stabilität, Hinzufügen von Funktionen, und so weiter.

Zusammenfassung

MVVM Light-Bindungen unterscheiden sich von XAML-Bindungen, die sie im Code anstelle von Markup erstellt werden. Allerdings wurden viele Stunden damit verbracht, und stellen Sie sicher, dass die API sauber ist. Ich nehmen jetzt dank mein guten Freund Corrado Cavalli für seine Unterstützung für die Implementierung der Bindung und Hilfe bei der Entwicklung eine Syntax zu erstellen, die so nah wie möglich an den Workflow der XAML-Bindung ist.

Darüber hinaus soll für ihre Hilfe Dank des Xamarin-Personals und insbesondere James Montemagno, überprüft der frühe Versionen von dieser Bindung-Framework und habe ich mir unglaublich wertvoll Rat.

Weitere Informationen und ein vollständiges Codebeispiel, einschließlich Windows Phone, Xamarin.Android, Xamarin.iOS und Xamarin.Forms, finden Sie meine Präsentation Xamarin zu entwickeln, aufgalasoft.ch/s/evolve14.


Laurent Bugnionist senior Director IdentityMine Inc., einem Microsoft-Partner arbeiten mit Technologien wie z. B. WPF, Silverlight, Xbox, Kinect, Windows Store, Windows Phone, Xamarin und UX Er lebt in Zürich in der Schweiz. Er ist außerdem Microsoft MVP, Microsoft Regional Director und Xamarin MVP.

Unser Dank gilt dem folgenden technischen Experten für die Durchsicht dieses Artikels: Kraig Brockschmidt (Microsoft), Norm Estabrook (Microsoft) und James Montemagno (Xamarin)