Xamarin.Forms Ausführliche Erläuterungen zum Schnellstart

In Xamarin.Forms Quickstart wurde die Notes-Anwendung erstellt. In diesem Artikel lassen wir die dafür erforderlichen Vorgänge noch einmal Revue passieren, sodass Sie die Funktionsweise von Xamarin.Forms-Shellanwendungen besser verstehen können.

Einführung in Visual Studio

In Visual Studio wird Code in Projektmappen und Projekten organisiert. Eine Projektmappe ist ein Container, der mindestens ein Projekt enthält. Ein Projekt kann z.B. eine Anwendung, eine unterstützende Bibliothek oder eine Testanwendung sein. Die Notes-Anwendung besteht wie im folgenden Screenshot gezeigt aus einer Projektmappe mit drei Projekten:

Visual Studio Projektmappen-Explorer

Diese Projekte sind folgende:

  • Notes: Dieses Projekt ist das .NET Standard-Klassenbibliotheksprojekt, das den gesamten freigegebenen Code und die gesamte freigegebene Benutzeroberfläche enthält.
  • Notes.Android: Dieses Projekt enthält Android-spezifischen Code und ist der Einstiegspunkt für die Android-Anwendung.
  • Notes.iOS: Dieses Projekt enthält iOS-spezifischen Code und ist der Einstiegspunkt für die iOS-Anwendung.

Struktur einer Xamarin.Forms-Anwendung

Der folgende Screenshot zeigt den Inhalt des .NET Standard-Bibliotheksprojekts „Notes“ in Visual Studio:

Phoneword-.NET Standard Project-Inhalt

Das Projekt verfügt über den Knoten Abhängigkeiten, der die Knoten NuGet und SDK enthält:

  • NuGet: , , Xamarin.Essentials Newtonsoft.Json und sqlite-net-pcl NuGet Pakete, die dem Projekt hinzugefügt wurden.
  • SDK: Das Metapaket, das auf den vollständigen Satz von NuGet Paketen verweist, die .NET Standard definieren.

Einführung in Visual Studio für Mac

Die Codeorganisation in Visual Studio für Mac baut auf Visual Studio auf und gliedert sich in Projektmappen und Projekte. Eine Projektmappe ist ein Container, der mindestens ein Projekt enthält. Ein Projekt kann z.B. eine Anwendung, eine unterstützende Bibliothek oder eine Testanwendung sein. Die Notes-Anwendung besteht wie im folgenden Screenshot gezeigt aus einer Projektmappe mit drei Projekten:

Visual Studio für Mac Projektmappenbereich

Diese Projekte sind folgende:

  • Notes: Dieses Projekt ist das .NET Standard-Klassenbibliotheksprojekt, das den gesamten freigegebenen Code und die gesamte freigegebene Benutzeroberfläche enthält.
  • Notes.Android: Dieses Projekt enthält Android-spezifischen Code und ist der Einstiegspunkt für Android-Anwendungen.
  • Notes.iOS: Dieses Projekt enthält iOS-spezifischen Code und ist der Einstiegspunkt für iOS-Anwendungen.

Struktur einer Xamarin.Forms-Anwendung

Der folgende Screenshot zeigt den Inhalt des .NET Standard-Bibliotheksprojekts „Notes“ in Visual Studio für Mac:

Phoneword .NET Standard Library Project Contents

Das Projekt verfügt über den Knoten Abhängigkeiten, der die Knoten NuGet und SDK enthält:

  • NuGet: , , Xamarin.Essentials Newtonsoft.Json und sqlite-net-pcl NuGet Pakete, die dem Projekt hinzugefügt wurden.
  • SDK: Das Metapaket, das auf den vollständigen Satz von NuGet Paketen verweist, die .NET Standard definieren.

Das Projekt besteht auch aus mehreren Dateien:

  • Data\NoteDatabase.cs: Diese Klasse enthält Code, mit dem die Datenbank erstellt wird und Daten aus ihr gelesen bzw. in sie geschrieben und aus ihr gelöscht werden.
  • Models\Note.cs: Diese Klasse definiert ein Modell, dessen Instanzen Daten zu jedem Hinweis in der Anwendung speichern.
  • Views\AboutPage.xaml: Das XAML-Markup für die -Klasse, das die Benutzeroberfläche für die About-Seite definiert.
  • Views\AboutPage.xaml.cs: Der CodeBehind für die -Klasse, die die Geschäftslogik enthält, die ausgeführt wird, wenn der Benutzer mit der Seite interagiert.
  • Views\NotesPage.xaml: Das XAML-Markup für die -Klasse, das die Benutzeroberfläche für die Seite definiert, die beim Starten der Anwendung angezeigt wird.
  • Views\NotesPage.xaml.cs: Der CodeBehind für die -Klasse, die die Geschäftslogik enthält, die ausgeführt wird, wenn der Benutzer mit der Seite interagiert.
  • Views\NoteEntryPage.xaml: Das XAML-Markup für die -Klasse, das die Benutzeroberfläche für die Seite definiert, die angezeigt wird, wenn der Benutzer eine Notiz eingibt.
  • Views\NoteEntryPage.xaml.cs: Der CodeBehind für die -Klasse, die die Geschäftslogik enthält, die ausgeführt wird, wenn der Benutzer mit der Seite interagiert.
  • App.xaml: Das XAML-Markup für die -Klasse, die ein Ressourcenwörterbuch für die Anwendung definiert.
  • App.xaml.cs: Der CodeBehind für die -Klasse, die für die Instanziierung der Shell-Anwendung und für die Behandlung von Anwendungslebenszyklusereignissen zuständig ist.
  • AppShell.xaml: Das XAML-Markup für die -Klasse, das die visuelle Hierarchie der Anwendung definiert.
  • AppShell.xaml.cs: Das CodeBehind für die -Klasse, die eine Route für die NoteEntryPage erstellt, sodass programmgesteuert zu navigiert werden kann.
  • AssemblyInfo.cs: Diese Datei enthält ein Anwendungsattribut für das Projekt, das auf Assemblyebene angewendet wird.

Weitere Informationen zum Aufbau einer Xamarin.iOS-Anwendung finden Sie unter Hello, iOS: Deep Dive (Hallo iOS: Ausführliche Informationen). Weitere Informationen zum Aufbau einer Xamarin.Android-Anwendung finden Sie unter Hello, Android: Deep Dive (Hallo Android: Ausführliche Informationen).

Architektur und Anwendungsgrundlagen

Eine Xamarin.Forms-Anwendung ist genauso aufgebaut wie eine traditionelle plattformübergreifende Anwendung. Freigegebener Code wird in der Regel in einer .NET Standard-Bibliothek platziert und von plattformspezifischen Anwendungen genutzt. Die folgende Abbildung bietet für die Notes-Anwendung einen Überblick über diese Beziehung:

Notes Architecture

Xamarin.Forms-Anwendungen enthalten eine einzelne Klasse namens App, um Startcode besser wiederverwenden zu können. Diese Klasse instanziiert die Anwendung auf jeder Seite, wie im folgenden Codebeispiel gezeigt:

using Xamarin.Forms;

namespace Notes
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
            MainPage = new AppShell();
        }
        // ...
    }
}

Dieser Code legt MainPage-Eigenschaft der App-Klasse auf das Objekt AppShell fest. Die AppShell-Klasse definiert die visuelle Hierarchie der Anwendung. Die Shell übernimmt diese visuelle Hierarchie und erzeugt die Benutzeroberfläche dafür. Weitere Informationen zum Definieren der visuellen Hierarchie einer Anwendung finden Sie unter Visuelle Anwendungshierarchie.

Außerdem enthält die Datei AssemblyInfo.cs ein einzelnes Anwendungsattribut, das auf Assemblyebene angewendet wird:

using Xamarin.Forms.Xaml;

[assembly: XamlCompilation(XamlCompilationOptions.Compile)]

Das Attribut XamlCompilation aktiviert den XAML-Compiler, sodass XAML direkt in der Zwischensprache kompiliert wird. Weitere Informationen finden Sie unter XAML Compilation (XAML-Kompilierung).

Starten der Anwendung auf jeder Plattform

Die Art und Weise, wie die Anwendung auf den verschiedenen Plattformen gestartet wird, ist spezifisch für die jeweilige Plattform.

iOS

Zum Aufrufen der Xamarin.Forms-Startseite in iOS definiert das Notes.iOS-Projekt die Klasse AppDelegate, die von der Klasse FormsApplicationDelegate erbt:

namespace Notes.iOS
{
    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
    {
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            global::Xamarin.Forms.Forms.Init();
            LoadApplication(new App());
            return base.FinishedLaunching(app, options);
        }
    }
}

Mit der FinishedLaunching-Außerkraftsetzung wird das Xamarin.Forms-Framework durch Aufrufen der Init-Methode initialisiert. Dadurch wird die iOS-spezifische Implementierung von Xamarin.Forms in die Anwendung geladen, bevor der Stammansichtscontroller durch den Aufruf der LoadApplication-Methode festgelegt wird.

Android

Zum Aufrufen der Xamarin.Forms-Startseite in Android enthält das Notes.Android-Projekt Code, der eine Aktivität (Activity) mit dem Attribut MainLauncher erstellt, wobei die Aktivität von der Klasse FormsAppCompatActivity erbt:

namespace Notes.Droid
{
    [Activity(Label = "Notes",
              Icon = "@mipmap/icon",
              Theme = "@style/MainTheme",
              MainLauncher = true,
              ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
            LoadApplication(new App());
        }
    }
}

Mit der OnCreate-Außerkraftsetzung wird das Xamarin.Forms-Framework durch Aufrufen der Init-Methode initialisiert. Dadurch wird die Android-spezifische Implementierung von Xamarin.Forms in die Anwendung geladen, bevor die Xamarin.Forms-Anwendung geladen wird.

Visuelle Anwendungshierarchie

Xamarin.Forms-Shellanwendungen definieren die visuelle Hierarchie der Anwendung in einer Klasse, die die Klasse Shell in Unterklassen unterteilt. In der Notes-Anwendung ist dies die Appshell-Klasse:

<Shell xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:views="clr-namespace:Notes.Views"
       x:Class="Notes.AppShell">
    <TabBar>
        <ShellContent Title="Notes"
                      Icon="icon_feed.png"
                      ContentTemplate="{DataTemplate views:NotesPage}" />
        <ShellContent Title="About"
                      Icon="icon_about.png"
                      ContentTemplate="{DataTemplate views:AboutPage}" />
    </TabBar>
</Shell>

Dieser XAML-Code besteht aus zwei Hauptobjekten:

  • TabBar. TabBar stellt die untere Registerkartenleiste dar und sollte verwendet werden, wenn das Navigationsmuster für die Anwendung Registerkarten unten verwendet. Das TabBar-Objekt ist dem Shell-Objekt untergeordnet.
  • ShellContent stellt die ContentPage-Objekte für jede Registerkarte in der TabBar dar. Jedes ShellContent-Objekt ist ein untergeordnetes Objekt des TabBar-Objekts.

Diese Objekte repräsentieren keine Benutzeroberfläche, sondern die Anordnung der visuellen Hierarchie einer Anwendung. Die Shell wird diese Objekte übernehmen und die Benutzeroberfläche für die Navigation der Inhalte erstellen. Daher definiert die AppShell-Klasse zwei Seiten, in denen über die unteren Registerkarten navigiert werden kann. Die Seiten werden bedarfsbasiert und als Reaktion auf die Navigation erstellt.

Weitere Informationen zu Shell-Anwendungen finden Sie unter Xamarin.Forms Shell .

Benutzeroberfläche

Beim Erstellen der Benutzeroberfläche einer Xamarin.Forms-Anwendung kommen verschiedene Steuerelementgruppen zum Einsatz:

  1. Pages: Seiten stellen plattformübergreifende Bildschirme für mobile Anwendungen dar. Die Notes-Anwendung verwendet die ContentPage-Klasse, um einzelne Bildschirme anzuzeigen. Weitere Informationen zu Seiten finden Sie unter Xamarin.Forms Pages .
  2. Ansichten: Ansichten sind die Steuerelemente, die auf der Benutzeroberfläche angezeigt werden, z. B. Bezeichnungen, Schaltflächen und Texteingabefelder. Die fertige Notes-Anwendung verwendet die Ansichten CollectionView, Editor und Button. Weitere Informationen zu Ansichten finden Sie unter Xamarin.Forms Views.
  3. Layouts: Layouts sind Container, die zum Erstellen von Ansichten in logischen Strukturen verwendet werden. Die Notes-Anwendung verwendet die Klasse StackLayout, um Ansichten in einem vertikalen Stapel anzuordnen, und die Klasse Grid, um Schaltflächen horizontal anzuordnen. Weitere Informationen zu Layouts finden Sie unter Xamarin.Forms Layouts .

Zur Laufzeit wird jedes Steuerelement seinem nativen Äquivalent zugeordnet. Dieses wird dann gerendert.

Layout

Die Notes-Anwendung verwendet die Klasse StackLayout, um die plattformübergreifende Anwendungsentwicklung zu vereinfachen, indem Anzeigen unabhängig von der Bildschirmgröße automatisch angeordnet werden. Alle untergeordneten Elemente werden nacheinander horizontal oder vertikal in der Reihenfolge positioniert, in der sie hinzugefügt wurden. Wie viel Speicherplatz der verwendet, hängt davon ab, wie die StackLayout Xamarin_Forms StackLayout _View_HorizontalOptions" data-linktype="absolute-path">and HorizontalOptions Xamarin_Forms _View_HorizontalOptions" data-linktype="absolute-path">-Eigenschaften festgelegt VerticalOptions sind. Standardmäßig StackLayout wird jedoch versucht, den gesamten Bildschirm zu verwenden.

Der folgende XAML-Code zeigt ein Beispiel für die Verwendung einer StackLayout-Klasse zur Gestaltung von NoteEntryPage:

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Notes.Views.NoteEntryPage"
             Title="Note Entry">
    ...    
    <StackLayout Margin="{StaticResource PageMargin}">
        <Editor Placeholder="Enter your note"
                Text="{Binding Text}"
                HeightRequest="100" />
        <Grid>
            ...
        </Grid>
    </StackLayout>    
</ContentPage>

Standardmäßig geht die Klasse StackLayout von einer vertikalen Ausrichtung aus. Sie kann jedoch in eine horizontale Ausrichtung geändert werden, indem der Xamarin_Forms _StackLayout_Orientation" data-linktype="absolute-path">-Eigenschaft auf den StackLayout.Orientation Xamarin_Forms StackLayout.Orientation _StackOrientation_Horizontal" data-linktype="absolute-path">-Enumerationsmember festgelegt StackOrientation.Horizontal wird.

Hinweis

Die Größe der Ansichten kann mithilfe der Eigenschaften HeightRequest und WidthRequest festgelegt werden.

Weitere Informationen zur -Klasse StackLayout finden Sie unter Xamarin.Forms StackLayout .

Reagieren auf eine Benutzerinteraktion

Ein in XAML definiertes Objekt kann ein Ereignis auslösen, das in der CodeBehind-Datei behandelt wird. Das folgende Codebeispiel zeigt die Methode OnSaveButtonClicked im CodeBehind für die Klasse NoteEntryPage, die als Reaktion auf das Ereignis Clicked ausgeführt wird, das über die Schaltfläche OnSaveButtonClicked ausgelöst wird.

async void OnSaveButtonClicked(object sender, EventArgs e)
{
    var note = (Note)BindingContext;
    note.Date = DateTime.UtcNow;
    if (!string.IsNullOrWhiteSpace(note.Text))
    {
        await App.Database.SaveNoteAsync(note);
    }
    await Shell.Current.GoToAsync("..");
}

Die Methode OnSaveButtonClicked speichert die Notiz in der Datenbank und wechselt zurück zur vorherigen Seite. Weitere Informationen zur Navigation finden Sie unter Navigation.

Hinweis

Die CodeBehind-Datei für eine XAML-Klasse kann auf ein Objekt zugreifen, das mit dem Namen, der ihm mit dem x:Name-Attribut zugewiesen wurde, in XAML definiert wurde. So wie bei C#-Variablen muss der diesem Attribut zugewiesene Wert mit einem Buchstaben oder Unterstrich beginnen und darf keine eingebetteten Leerzeichen enthalten.

Die Verknüpfung der Schaltfläche „Speichern“ mit der OnSaveButtonClicked-Methode erfolgt im XAML-Markup für die Klasse NoteEntryPage:

<Button Text="Save"
        Clicked="OnSaveButtonClicked" />

Listen

CollectionView ist für die Anzeige einer Sammlung von Elementen auf dem Bildschirm zuständig. Standardmäßig werden Listenelemente vertikal angezeigt, und jedes Element wird in einer einzelnen Zeile angezeigt.

Das folgende Codebeispiel zeigt die Klasse CollectionView über die NotesPage:

<CollectionView x:Name="collectionView"
                Margin="{StaticResource PageMargin}"
                SelectionMode="Single"
                SelectionChanged="OnSelectionChanged">
    <CollectionView.ItemsLayout>
        <LinearItemsLayout Orientation="Vertical"
                           ItemSpacing="10" />
    </CollectionView.ItemsLayout>
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <StackLayout>
                <Label Text="{Binding Text}"
                       FontSize="Medium" />
                <Label Text="{Binding Date}"
                       TextColor="{StaticResource TertiaryColor}"
                       FontSize="Small" />
            </StackLayout>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

Das Layout jeder Zeile in der wird innerhalb des CollectionView Xamarin_Forms CollectionView _ItemsView_1_ItemTemplate" data-linktype="absolute-path">-Elements definiert und verwendet die Datenbindung, um alle Notizen CollectionView.ItemTemplate anzuzeigen, die von der Anwendung abgerufen werden. Die Xamarin_Forms _ItemsView_1_ItemsSource" data-linktype="absolute-path">-Eigenschaft wird CollectionView.ItemsSource in CollectionView.ItemsSourceauf die Datenquelle festgelegt:

protected override async void OnAppearing()
{
    base.OnAppearing();

    collectionView.ItemsSource = await App.Database.GetNotesAsync();
}

Dieser Code füllt den CollectionView mit allen in der Datenbank gespeicherten Notizen auf und wird ausgeführt, wenn die Seite angezeigt wird.

Bei Auswahl eines Elements in CollectionView wird das Ereignis SelectionChanged ausgelöst. Ein Ereignishandler mit dem Namen OnSelectionChanged wird ausgeführt, wenn das Ereignis ausgelöst wird:

async void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (e.CurrentSelection != null)
    {
        // ...
    }
}

Das Ereignis SelectionChanged kann auf das Objekt zugreifen, das dem Element über die Eigenschaft e.CurrentSelection zugeordnet wurde.

Weitere Informationen zur -Klasse CollectionView finden Sie unter Xamarin.Forms CollectionView .

Die Navigation erfolgt in einer Shell-Anwendung durch Angabe eines URI, zu dem navigiert werden soll. Navigations-URIs bestehen aus drei Komponenten:

  • Eine Route, die den Pfad zu Inhalt definiert, der als Teil der visuellen Shell-Hierarchie vorhanden ist.
  • Eine Seite. Seiten, die in der visuellen Shell-Hierarchie nicht vorhanden sind, können von überall innerhalb einer Shell-Anwendung per Push an den Navigationsstapel übertragen werden. Beispielsweise wird die NoteEntryPage nicht in der visuellen Shellhierarchie definiert, sondern kann bei Bedarf per Push an den Navigationsstapel übertragen werden.
  • Mindestens ein Abfrageparameter. Abfrageparameter sind Parameter, die während der Navigation an die Zielseite übergeben werden können.

Ein Navigations-URI muss nicht alle drei Komponenten enthalten, aber wenn dies der Fall ist, wird diese Struktur verwendet: //route/page?queryParameters.

Hinweis

Routen können über die Eigenschaft Route für Elemente in der visuellen Shellhierarchie definiert werden. Wenn die Eigenschaft Route jedoch nicht festgelegt ist (z. B. in der Notes-Anwendung), wird zur Laufzeit eine Route generiert.

Weitere Informationen zur Shellnavigation finden Sie unter Xamarin.Forms Shell navigation .

Registrieren von Routen

Zum Navigieren zu einer Seite, die in der visuellen Hierarchie der Shell nicht vorhanden ist, muss die Seite zuerst beim Shellroutingsystem registriert werden. Dafür wird die Routing.RegisterRoute-Methode verwendet. In der Notes-Anwendung erfolgt dies im AppShell-Konstruktor:

public partial class AppShell : Shell
{
    public AppShell()
    {
        // ...
        Routing.RegisterRoute(nameof(NoteEntryPage), typeof(NoteEntryPage));
    }
}

In diesem Beispiel wird eine Route mit namens NoteEntryPage für den NoteEntryPage-Typ registriert. Diese Seite kann dann von überall in der Anwendung per URI-basierter Navigation aufgerufen werden.

Durchführen der Navigation

Die Navigation wird von der GoToAsync-Methode ausgeführt. Diese akzeptiert ein Argument, das die Route darstellt, zu der navigiert werden soll:

await Shell.Current.GoToAsync("NoteEntryPage");

In diesem Beispiel wird zu NoteEntryPage navigiert.

Wichtig

Ein Navigationsstapel wird erstellt, wenn zu einer Seite navigiert wird, die sich nicht in der visuellen Shellhierarchie befindet.

Beim Navigieren zu einer Seite können Daten als Abfrageparameter an die Seite übergeben werden:

async void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (e.CurrentSelection != null)
    {
        // Navigate to the NoteEntryPage, passing the ID as a query parameter.
        Note note = (Note)e.CurrentSelection.FirstOrDefault();
        await Shell.Current.GoToAsync($"{nameof(NoteEntryPage)}?{nameof(NoteEntryPage.ItemId)}={note.ID.ToString()}");
    }
}

Dieses Beispiel ruft das aktuell ausgewählte Element in CollectionView ab und navigiert zu NoteEntryPage. Dabei wird der Wert der ID-Eigenschaft des Note-Objekts als Abfrageparameter an die NoteEntryPage.ItemId-Eigenschaft übergeben.

Um die übergebenen Daten zu empfangen, wird die NoteEntryPage-Klasse mit dem QueryPropertyAttribute versehen.

[QueryProperty(nameof(ItemId), nameof(ItemId))]
public partial class NoteEntryPage : ContentPage
{
    public string ItemId
    {
        set
        {
            LoadNote(value);
        }
    }
    // ...
}

Das erste Argument für das QueryPropertyAttribute gibt an, dass die Eigenschaft ItemId die Daten empfangen soll, das zweite Argument gibt die Abfrageparameter-ID an. Das QueryPropertyAttribute im oben stehenden Beispiel legt somit fest, dass die ItemId-Eigenschaft die im ItemId-Abfrageparameter übergebenen Daten vom URI im GoToAsync-Methodenaufruf erhält. Die ItemId-Eigenschaft ruft dann die LoadNote-Methode auf, um die Notiz vom Gerät abzurufen.

Die Rückwärtsnavigation wird ausgeführt, indem ".." als Argument für die GoToAsync-Methode angegeben wird:

await Shell.Current.GoToAsync("..");

Weitere Informationen zur Rückwärtsnavigation finden Sie unter Rückwärtsnavigation.

Datenbindung

Datenbindung wird verwendet, um zu vereinfachen, wie eine Xamarin.Forms-Anwendung Daten anzeigt und mit ihnen interagiert. Sie stellt eine Verbindung zwischen der Benutzeroberfläche und der zugrundeliegenden Anwendung her. Die BindableObject-Klasse beinhaltet einen Großteil der Infrastruktur, um die Datenbindung zu unterstützen.

Bei der Datenbindung werden zwei Objekte miteinander verbunden: die Quelle und das Ziel. Das Quellobjekt stellt die Daten bereit. Das Zielobjekt verwendet Daten aus dem Quellobjekt (und zeigt diese häufig an). Beispielsweise bindet ein (-Zielobjekt) häufig seine Editor Xamarin_FormsEditor _InputView_Text" data-linktype="absolute-path">-Eigenschaft an eine öffentliche Eigenschaft in einem Textstring Quellobjekt. Text Das folgende Diagramm veranschaulicht die Bindungsbeziehung:

Datenbindung

Der Hauptvorteil der Datenbindung ist, dass Sie Daten zwischen Ihren Ansichten und der Datenquelle nicht mehr synchronisieren müssen. Änderungen im Quellobjekt werden automatisch mithilfe von Push intern vom Bindungsframework in das Zielobjekt übertragen, und Änderungen im Zielobjekt können optional wieder zurück in das Quellobjekt übertragen werden.

Die Datenbindung wird in zwei Schritten eingerichtet:

In der Notes-Anwendung ist das Bindungsziel das , das eine Notiz anzeigt, während die instanz, die als EditorNote Xamarin_Forms Editor _BindableObject_BindingContext" data-linktype="absolute-path">BindingContext von NoteEntryPage festgelegt ist, die Bindungsquelle ist. Anfänglich wird der BindingContext der NoteEntryPage festgelegt, wenn der Seitenkonstruktor ausgeführt wird:

public NoteEntryPage()
{
    // ...
    BindingContext = new Note();
}

In diesem Beispiel wird der BindingContext der Seite auf ein neues Note-Element festgelegt, wenn die NoteEntryPage erstellt wird. Damit wird das Szenario des Hinzufügens einer neuen Notiz zur Anwendung verarbeitet.

Außerdem kann der BindingContext der Seite auch festgelegt werden, wenn die Navigation zur NoteEntryPage erfolgt, vorausgesetzt, dass auf der NotesPage eine vorhandene Notiz ausgewählt wurde:

[QueryProperty(nameof(ItemId), nameof(ItemId))]
public partial class NoteEntryPage : ContentPage
{
    public string ItemId
    {
        set
        {
            LoadNote(value);
        }

        async void LoadNote(string itemId)
        {
            try
            {
                int id = Convert.ToInt32(itemId);
                // Retrieve the note and set it as the BindingContext of the page.
                Note note = await App.Database.GetNoteAsync(id);
                BindingContext = note;
            }
            catch (Exception)
            {
                Console.WriteLine("Failed to load note.");
            }
        }    
        // ...    
    }
}

In diesem Beispiel wird bei Ausführung einer Seitennavigation der BindingContext der Seite auf das ausgewählte Note-Objekt festgelegt, nachdem es aus der Datenbank abgerufen wurde.

Wichtig

Während die Xamarin_Forms _BindableObject_BindingContext" data-linktype="absolute-path">-Eigenschaft jedes Zielobjekts einzeln festgelegt werden kann, ist BindingContext dies nicht erforderlich. BindingContext BindingContext ist eine spezielle Eigenschaft, die von allen zugehörigen untergeordneten Elementen geerbt wird. Wenn die Eigenschaft BindingContext auf der Seite ContentPage auf eine Note-Instanz festgelegt wird, verfügen folglich alle untergeordneten Elemente der Seite ContentPage über die gleiche BindingContext-Eigenschaft und können eine Bindung an öffentliche Eigenschaften des Note-Objekts vornehmen.

Der Editor auf der Seite NoteEntryPage bindet dann die Eigenschaft Text des Objekts Note:

<Editor Placeholder="Enter your note"
        Text="{Binding Text}" />

Eine Bindung zwischen der Xamarin_Forms _InputView_Text" data-linktype="absolute-path">-Eigenschaft und der -Eigenschaft des Editor.TextText Quellobjekts wird hergestellt. Editor.Text Am Editor vorgenommene Änderungen werden automatisch an das Note-Objekt weitergegeben. Gleichermaßen aktualisiert die Xamarin.Forms-Bindungs-Engine auch die Inhalte von Editor, wenn Änderungen an der Eigenschaft Note.Text vorgenommen werden. Dies wird als bidirektionale Bindung bezeichnet.

Weitere Informationen zur Datenbindung finden Sie unter Xamarin.Forms Data Binding .

Format

Xamarin.Forms-Anwendungen enthalten häufig mehrere visuelle Elemente, die identisch dargestellt werden. Es kann sehr eintönig und fehleranfällig sein, die Darstellung der visuellen Elemente einzeln festzulegen. Stattdessen können Formatvorlagen, die die Darstellung definieren, erstellt und anschließend auf die erforderlichen visuellen Elemente angewendet werden.

Die Klasse Style gruppiert eine Sammlung von Eigenschaftswerten in ein Objekt, das anschließend auf mehrere Instanzen von visuellen Elementen angewendet werden kann. Formatvorlagen werden entweder auf Anwendungs-, auf Ansichts- oder auf Seitenebene in einer ResourceDictionary-Klasse gespeichert. Die Entscheidung, wo Sie eine Style-Klasse definieren, hat Einfluss darauf, wo Sie sie verwenden können:

  • Eine auf Anwendungsebene definierte Style-Instanz können Sie für die gesamte Anwendung nutzen.
  • Eine auf Seitenebene definierte Style-Instanz können Sie nur auf die jeweilige Seite und deren untergeordneten Seiten anwenden.
  • Eine auf Ansichtsebene definierte Style-Instanz können Sie nur auf die jeweilige Ansicht und deren untergeordneten Ansichten anwenden.

Wichtig

Alle Formatvorlagen, die in der gesamten Anwendung verwendet werden, werden im Ressourcenverzeichnis der Anwendung gespeichert, damit eine Duplizierung verhindert wird. XAML-Code, der für eine Seite spezifisch ist, sollte jedoch nicht im Ressourcenverzeichnis der Anwendung enthalten sein, da die Ressourcen dann beim Starten der Anwendung analysiert werden und nicht, wenn dies auf einer Seite erforderlich ist. Weitere Informationen finden Sie unter Verringern der Größe des Ressourcenverzeichnisses der Anwendung.

Jede Style Instanz enthält eine Auflistung von einem oder mehreren Setter -Objekten, wobei jedes -Objekt Setter über einen Xamarin_Forms Style _Setter_Property" data-linktype="absolute-path">und einen Xamarin_Forms PropertySetter _Setter_Value" data-linktype="absolute-path">Value verfügt. Property ist der Name der bindbaren Eigenschaft des Elements, auf das die Formatvorlage angewendet wird, und Value ist der Wert, der auf die Eigenschaft angewendet wird. Das folgende Codebeispiel zeigt eine Formatvorlage von NoteEntryPage:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Notes.Views.NoteEntryPage"
             Title="Note Entry">
    <ContentPage.Resources>
        <!-- Implicit styles -->
        <Style TargetType="{x:Type Editor}">
            <Setter Property="BackgroundColor"
                    Value="{StaticResource AppBackgroundColor}" />
        </Style>
        ...
    </ContentPage.Resources>
    ...
</ContentPage>

Diese Formatvorlage wird auf alle Editor-Instanzen auf der Seite angewendet.

Beim Erstellen eines Style ist immer die Xamarin_Forms Style _Style_TargetType" data-linktype="absolute-path">-Eigenschaft TargetType erforderlich.

Hinweis

Xamarin.Forms-Anwendungen werden normalerweise mithilfe von XAML-Formatvorlagen formatiert. Xamarin.Forms unterstützt jedoch auch das Formatieren von visuellen Elementen mithilfe von Cascading Stylesheets (CSS). Weitere Informationen finden Sie unter Styling Xamarin.Forms apps using Cascading Style Sheets (CSS).

Weitere Informationen zu XAML-Stilen finden Sie unter Styling Xamarin.Forms Apps using XAML Styles .

Testen und Bereitstellen

Sowohl Visual Studio für Mac als auch Visual Studio stellen viele Optionen zum Testen und Bereitstellen einer Anwendung bereit. Das Debuggen von Anwendungen ist ein üblicher Vorgang im Lebenszyklus der Anwendungsentwicklung und trägt dazu bei, Codeprobleme zu diagnostizieren. Weitere Informationen finden Sie unter Festlegen eines Haltepunkts, Step Through Code (Detailliertes Durchlaufen von Code) und Output Information to the Log Window (Ausgabeinformationen an das Protokollfenster).

Simulatoren eigenen sich hervorragend für die Bereitstellung und das Testen einer Anwendung. Außerdem bieten sie nützliche Funktionen zum Testen von Anwendungen. Allerdings verwenden Benutzer die endgültige Anwendung nicht in einem Simulator. Daher sollte die Anwendungen frühzeitig und häufig auf echten Geräten getestet werden. Weitere Informationen zur Bereitstellung von iOS-Geräten finden Sie unter Device Provisioning (Gerätebereitstellung). Weitere Informationen zur Bereitstellung von Android-Geräten finden Sie unter Set Up Device for Development (Einrichten eines Geräts für die Entwicklung).

Nächste Schritte

In diesem Artikel wurden die Grundlagen der Anwendungsentwicklung mit der Xamarin.Forms-Shell erläutert. Vorgeschlagene nächste Schritte umfassen das Lesen über folgende Funktionen:

  • Die Xamarin.Forms-Shell reduziert die Komplexität der Entwicklung mobiler Anwendungen, indem die grundlegenden Features bereitgestellt werden, die von den meisten mobilen Anwendungen benötigt werden. Weitere Informationen finden Sie unter Xamarin.Forms Shell.
  • Beim Erstellen der Benutzeroberfläche einer Xamarin.Forms-Anwendung kommen verschiedene Steuerelementgruppen zum Einsatz. Weitere Informationen finden Sie unter Steuerelementreferenz.
  • Bei der Datenbindung werden die Eigenschaften von zwei Objekten verknüpft. Dadurch werden Änderungen an einer Eigenschaft automatisch in der anderen widergespiegelt. Weitere Informationen finden Sie unter Datenbindung.
  • Xamarin.Forms stellt abhängig vom verwendeten Seitentyp eine Reihe unterschiedlicher Seitennavigationsfunktionen bereit. Weitere Informationen finden Sie unter Navigation.
  • Stile können repetitives Markup reduzieren und erleichtern Änderungen an der Darstellung von Anwendungen. Weitere Informationen finden Sie unter Styling Xamarin.Forms Apps.
  • Datenvorlagen bieten die Möglichkeit, die Darstellung von Daten für unterstützte Ansichten zu definieren. Weitere Informationen finden Sie unter Datenvorlagen.
  • Zudem können durch Effekte native Steuerelemente auf den einzelnen Plattformen angepasst werden. Effekte werden in plattformspezifischen Projekten erstellt, indem Unterklassen für die PlatformEffect-Klasse erstellt werden. Sie werden verarbeitet, indem sie an das entsprechende Xamarin.Forms-Steuerelement angefügt werden. Weitere Informationen finden Sie unter Effekte.
  • Die einzelnen Seiten, Layouts und Ansichten werden auf jeder Plattform auf unterschiedliche Weise über eine Renderer-Klasse gerendert. Diese erstellt ein natives Steuerelement, ordnet dieses auf dem Bildschirm an und fügt das im freigegebenen Code angegebene Verhalten hinzu. Entwickler können ihre eigenen benutzerdefinierten Renderer-Klassen implementieren, um die Darstellung und/oder das Verhalten eines Steuerelements anzupassen. Weitere Informationen finden Sie unter Custom Renderers (Benutzerdefinierte Renderer).
  • Freigegebener Code kann über die DependencyService-Klasse auf eine native Funktion zugreifen. Weitere Informationen finden Sie unter Accessing Native Features with DependencyService (Zugreifen auf native Funktionen über DependencyService).

Auf Channel 9 und auf YouTube finden Sie weitere Videos zu Xamarin.