RessourcenverzeichnisseResource Dictionaries

Beispiel herunterladen Das Beispiel herunterladenDownload Sample Download the sample

XAML-Ressourcen sind Definitionen von Objekten, die in einer xamarin. Forms-Anwendung freigegeben und wieder verwendet werden können. Diese Ressourcen Objekte werden in einem Ressourcen Wörterbuch gespeichert.XAML resources are definitions of objects that can be shared and re-used throughout a Xamarin.Forms application. These resource objects are stored in a resource dictionary.

Bei einem ResourceDictionary handelt es sich um ein Repository für Ressourcen, die von einer xamarin. Forms-Anwendung verwendet werden.A ResourceDictionary is a repository for resources that are used by a Xamarin.Forms application. Typische Ressourcen, die in einem ResourceDictionary gespeichert sind, umfassen Stile, Steuerelement Vorlagen, Datenvorlagen, Farben und Konverter.Typical resources that are stored in a ResourceDictionary include styles, control templates, data templates, colors, and converters.

In XAML können Ressourcen, die in einem ResourceDictionary gespeichert werden, mithilfe der StaticResource Markup Erweiterung abgerufen und auf Elemente angewendet werden.In XAML, resources that are stored in a ResourceDictionary can then be retrieved and applied to elements by using the StaticResource markup extension. In C#können Ressourcen auch in einem ResourceDictionary definiert und dann mithilfe eines zeichenfolgenbasierten Indexers abgerufen und auf Elemente angewendet werden.In C#, resources can also be defined in a ResourceDictionary and then retrieved and applied to elements by using a string-based indexer. Allerdings gibt es kaum Vorteile bei der Verwendung einer ResourceDictionary C#in, da freigegebene Objekte einfach als Felder oder Eigenschaften gespeichert werden können und direkt auf Sie zugegriffen werden kann, ohne Sie zuerst von einem Wörterbuch abrufen zu müssen.However, there's little advantage to using a ResourceDictionary in C#, as shared objects can simply be stored as fields or properties, and accessed directly without having to first retrieve them from a dictionary.

Erstellen und Verwenden eines ResourceDictionaryCreate and consume a ResourceDictionary

Ressourcen werden in einem ResourceDictionary definiert, der anschließend auf eine der folgenden Resources Eigenschaften festgelegt wird:Resources are defined in a ResourceDictionary that is then set to one of the following Resources properties:

Ein xamarin. Forms-Programm enthält nur eine Klasse, die von Application abgeleitet ist, aber häufig viele Klassen verwendet, die von VisualElementabgeleitet sind, einschließlich Seiten, Layouts und Steuerelemente.A Xamarin.Forms program contains only one class that derives from Application but often makes use of many classes that derive from VisualElement, including pages, layouts, and controls. Für jedes dieser Objekte kann die Resources-Eigenschaft auf einen ResourceDictionaryfestgelegt werden.Any of these objects can have its Resources property set to a ResourceDictionary. Die Entscheidung, wo ein bestimmtes ResourceDictionary platziert werden soll, wirkt sich auf die Verwendung der Ressourcen aus:Choosing where to put a particular ResourceDictionary impacts where the resources can be used:

  • Ressourcen in einer ResourceDictionary, die an eine Ansicht wie Button oder Label angefügt ist, können nur auf dieses bestimmte Objekt angewendet werden. Dies ist daher nicht sehr nützlich.Resources in a ResourceDictionary that is attached to a view such as Button or Label can only be applied to that particular object, so this is not very useful.
  • Ressourcen in einem ResourceDictionary, die an ein Layout wie StackLayout oder Grid angefügt sind, können auf das Layout und alle untergeordneten Elemente dieses Layouts angewendet werden.Resources in a ResourceDictionary attached to a layout such as StackLayout or Grid can be applied to the layout and all the children of that layout.
  • Ressourcen in einer ResourceDictionary, die auf der Seitenebene definiert sind, können auf die Seite und alle untergeordneten Elemente angewendet werden.Resources in a ResourceDictionary defined at the page level can be applied to the page and to all its children.
  • Ressourcen in einer ResourceDictionary, die auf Anwendungsebene definiert sind, können in der gesamten Anwendung angewendet werden.Resources in a ResourceDictionary defined at the application level can be applied throughout the application.

Der folgende XAML-Code zeigt Ressourcen, die auf Anwendungsebene definiert sind ResourceDictionary in der Datei app. XAML , die als Teil des xamarin. Forms-Standardprogramms erstellt wurde:The following XAML shows resources defined in an application level ResourceDictionary in the App.xaml file created as part of the standard Xamarin.Forms program:

<Application ...>
    <Application.Resources>
        <ResourceDictionary>
            <Color x:Key="PageBackgroundColor">Yellow</Color>
            <Color x:Key="HeadingTextColor">Black</Color>
            <Color x:Key="NormalTextColor">Blue</Color>
            <Style x:Key="LabelPageHeadingStyle" TargetType="Label">
                <Setter Property="FontAttributes" Value="Bold" />
                <Setter Property="HorizontalOptions" Value="Center" />
                <Setter Property="TextColor" Value="{StaticResource HeadingTextColor}" />
            </Style>
        </ResourceDictionary>
    </Application.Resources>
</Application>

In dieser ResourceDictionary werden drei Color Ressourcen und eine Style Ressource definiert.This ResourceDictionary defines three Color resources and a Style resource. Weitere Informationen zum App-Klasse finden Sie unter App-Klasse.For more information about the App class, see App Class.

Ab xamarin. Forms 3,0 sind die expliziten ResourceDictionary Tags nicht erforderlich.Beginning in Xamarin.Forms 3.0, the explicit ResourceDictionary tags are not required. Das ResourceDictionary Objekt wird automatisch erstellt, und Sie können die Ressourcen direkt zwischen den Resources Eigenschaften-Element-Tags einfügen:The ResourceDictionary object is created automatically, and you can insert the resources directly between the Resources property-element tags:

<Application ...>
    <Application.Resources>
        <Color x:Key="PageBackgroundColor">Yellow</Color>
        <Color x:Key="HeadingTextColor">Black</Color>
        <Color x:Key="NormalTextColor">Blue</Color>
        <Style x:Key="LabelPageHeadingStyle" TargetType="Label">
            <Setter Property="FontAttributes" Value="Bold" />
            <Setter Property="HorizontalOptions" Value="Center" />
            <Setter Property="TextColor" Value="{StaticResource HeadingTextColor}" />
        </Style>
    </Application.Resources>
</Application>

Jede Ressource verfügt über einen Schlüssel, der mit dem x:Key-Attribut angegeben wird, dessen Wörterbuch Schlüssel in der ResourceDictionarywird.Each resource has a key that is specified using the x:Key attribute, which becomes it dictionary key in the ResourceDictionary. Der Schlüssel wird verwendet, um eine Ressource aus dem ResourceDictionary von der StaticResource Markup Erweiterung abzurufen, wie im folgenden XAML-Codebeispiel veranschaulicht, das zusätzliche Ressourcen zeigt, die innerhalb der StackLayoutdefiniert sind:The key is used to retrieve a resource from the ResourceDictionary by the StaticResource markup extension, as demonstrated in the following XAML code example that shows additional resources defined within the StackLayout:

<StackLayout Margin="0,20,0,0">
  <StackLayout.Resources>
    <ResourceDictionary>
      <Style x:Key="LabelNormalStyle" TargetType="Label">
        <Setter Property="TextColor" Value="{StaticResource NormalTextColor}" />
      </Style>
      <Style x:Key="MediumBoldText" TargetType="Button">
        <Setter Property="FontSize" Value="Medium" />
        <Setter Property="FontAttributes" Value="Bold" />
      </Style>
    </ResourceDictionary>
  </StackLayout.Resources>
  <Label Text="ResourceDictionary Demo" Style="{StaticResource LabelPageHeadingStyle}" />
    <Label Text="This app demonstrates consuming resources that have been defined in resource dictionaries."
           Margin="10,20,10,0"
           Style="{StaticResource LabelNormalStyle}" />
    <Button Text="Navigate"
            Clicked="OnNavigateButtonClicked"
            TextColor="{StaticResource NormalTextColor}"
            Margin="0,20,0,0"
            HorizontalOptions="Center"
            Style="{StaticResource MediumBoldText}" />
</StackLayout>

Die erste Label Instanz Ruft die LabelPageHeadingStyle Ressource ab, die auf der ResourceDictionaryauf Anwendungsebene definiert ist, und nutzt Sie, wobei die zweite Label Instanz die LabelNormalStyle Ressource abruft und nutzt, die auf der Steuerungsebene ResourceDictionarydefiniert ist.The first Label instance retrieves and consumes the LabelPageHeadingStyle resource defined in the application level ResourceDictionary, with the second Label instance retrieving and consuming the LabelNormalStyle resource defined in the control level ResourceDictionary. Ebenso Ruft die Button Instanz die NormalTextColor Ressource ab, die auf der ResourceDictionaryEbene der Anwendungsebene definiert ist, und nutzt Sie, und die MediumBoldText Ressource, die auf der Steuerelement Ebene ResourceDictionarydefiniert ist.Similarly, the Button instance retrieves and consumes the NormalTextColor resource defined in the application level ResourceDictionary, and the MediumBoldText resource defined in the control level ResourceDictionary. Dies ergibt die in den folgenden Screenshots gezeigte Darstellung:This results in the appearance shown in the following screenshots:

verbrauchen von ResourceDictionary-RessourcenConsuming ResourceDictionary Resources

Hinweis

Ressourcen, die auf eine einzelne Seite spezifisch sind, darf nicht in einer Anwendung auf Ressourcenverzeichnis, daher enthalten sein, die Ressourcen dann beim Start der Anwendung nicht analysiert werden soll, bei einer Seite erforderlich.Resources that are specific to a single page shouldn't be included in an application level resource dictionary, as such resources will then be parsed at application startup instead of when required by a page. Weitere Informationen finden Sie unter reduzieren der Größe des Anwendungs Ressourcen Wörterbuchs.For more information, see Reduce the Application Resource Dictionary Size.

Ressourcen überschreibenOverride resources

Wenn ResourceDictionary Ressourcen x:Key Attributwerte gemeinsam nutzen, haben Ressourcen, die in der Sicht Hierarchie niedriger definiert sind, Vorrang vor den höheren Werten.When ResourceDictionary resources share x:Key attribute values, resources defined lower in the view hierarchy will take precedence over those defined higher up. Beispielsweise wird das Festlegen der PageBackgroundColor Ressource auf die Blue auf Anwendungsebene von einer PageBackgroundColor Ressource auf Seitenebene überschrieben, die auf Yellowfestgelegt ist.For example, setting the PageBackgroundColor resource to Blue at the application level will be overridden by a page level PageBackgroundColor resource set to Yellow. Ebenso wird eine PageBackgroundColor Ressource auf Seitenebene durch eine Steuerelement Ebene PageBackgroundColor Ressource überschrieben.Similarly, a page level PageBackgroundColor resource will be overridden by a control level PageBackgroundColor resource. Diese Priorität wird im folgenden XAML-Codebeispiel veranschaulicht:This precedence is demonstrated by the following XAML code example:

<ContentPage ... BackgroundColor="{StaticResource PageBackgroundColor}">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Color x:Key="PageBackgroundColor">Blue</Color>
            <Color x:Key="NormalTextColor">Yellow</Color>
        </ResourceDictionary>
    </ContentPage.Resources>
    <StackLayout Margin="0,20,0,0">
        ...
        <Label Text="ResourceDictionary Demo" Style="{StaticResource LabelPageHeadingStyle}" />
        <Label Text="This app demonstrates consuming resources that have been defined in resource dictionaries."
               Margin="10,20,10,0"
               Style="{StaticResource LabelNormalStyle}" />
        <Button Text="Navigate"
                Clicked="OnNavigateButtonClicked"
                TextColor="{StaticResource NormalTextColor}"
                Margin="0,20,0,0"
                HorizontalOptions="Center"
                Style="{StaticResource MediumBoldText}" />
    </StackLayout>
</ContentPage>

Die ursprünglichen PageBackgroundColor und NormalTextColor Instanzen, die auf Anwendungsebene definiert sind, werden durch die PageBackgroundColor und NormalTextColor Instanzen überschrieben, die auf der Seitenebene definiert sind.The original PageBackgroundColor and NormalTextColor instances, defined at the application level, are overridden by the PageBackgroundColor and NormalTextColor instances defined at page level. Aus diesem Grund die Hintergrundfarbe ist Blau, und der Text auf der Seite wird Gelb, wie in den folgenden Screenshots veranschaulicht:Therefore, the page background color becomes blue, and the text on the page becomes yellow, as demonstrated in the following screenshots:

Überschreiben von ResourceDictionary-RessourcenOverriding ResourceDictionary Resources

Beachten Sie jedoch, dass die Hintergrund Leiste des NavigationPage immer noch gelb ist, da die Eigenschaft BarBackgroundColor auf den Wert der PageBackgroundColor Ressource festgelegt ist, die auf der Ebene der Anwendungs ResourceDictionaryEbene definiert ist.However, note that the background bar of the NavigationPage is still yellow, because the BarBackgroundColor property is set to the value of the PageBackgroundColor resource defined in the application level ResourceDictionary.

Dies ist eine weitere Möglichkeit, um ResourceDictionary Rangfolge zu betrachten: Wenn der XAML-Parser auf eine StaticResourcestößt, sucht er nach einem passenden Schlüssel, indem er die visuelle Struktur durchsucht, wobei die erste gefundene Übereinstimmung verwendet wird.Here's another way to think about ResourceDictionary precedence: When the XAML parser encounters a StaticResource, it searches for a matching key by traveling up through the visual tree, using the first match it finds. Wenn diese Suche auf der Seite endet und der Schlüssel noch immer nicht gefunden wurde, durchsucht der XAML-Parser die ResourceDictionary, die an das App Objekt angefügt ist.If this search ends at the page and the key still hasn't been found, the XAML parser searches the ResourceDictionary attached to the App object. Wenn der Schlüssel nicht gefunden wird, wird eine Ausnahme ausgelöst.If the key is still not found, an exception is raised.

Eigenständige Ressourcen WörterbücherStand-alone resource dictionaries

Eine von ResourceDictionary abgeleitete Klasse kann sich auch in einer separaten eigenständigen Datei befinden.A class derived from ResourceDictionary can also be in a separate stand-alone file. Die resultierende Datei kann für Anwendungen genutzt werden.The resultant file can then be shared among applications.

Um eine solche Datei zu erstellen, fügen Sie dem Projekt eine neue Inhaltsansicht oder ein Inhaltsseiten Element hinzu (aber keine Inhaltsansicht oder Inhaltsseite mit C# nur einer Datei).To create such a file, add a new Content View or Content Page item to the project (but not a Content View or Content Page with only a C# file). Ändern Sie in der XAML- C# Datei und-Datei den Namen der Basisklasse von ContentView oder ContentPage in ResourceDictionary.In both the XAML file and C# file, change the name of the base class from ContentView or ContentPage to ResourceDictionary. In der XAML-Datei ist der Name der Basisklasse Element der obersten Ebene.In the XAML file, the name of the base class is the top-level element.

Das folgende XAML-Beispiel zeigt eine ResourceDictionary mit dem Namen MyResourceDictionary:The following XAML example shows a ResourceDictionary named MyResourceDictionary:

<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                    x:Class="ResourceDictionaryDemo.MyResourceDictionary">
    <DataTemplate x:Key="PersonDataTemplate">
        <ViewCell>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="0.5*" />
                    <ColumnDefinition Width="0.2*" />
                    <ColumnDefinition Width="0.3*" />
                </Grid.ColumnDefinitions>
                <Label Text="{Binding Name}" TextColor="{StaticResource NormalTextColor}" FontAttributes="Bold" />
                <Label Grid.Column="1" Text="{Binding Age}" TextColor="{StaticResource NormalTextColor}" />
                <Label Grid.Column="2" Text="{Binding Location}" TextColor="{StaticResource NormalTextColor}" HorizontalTextAlignment="End" />
            </Grid>
        </ViewCell>
    </DataTemplate>
</ResourceDictionary>

Diese ResourceDictionary enthält eine einzelne Ressource, bei der es sich um ein Objekt vom Typ DataTemplatehandelt.This ResourceDictionary contains a single resource, which is an object of type DataTemplate.

Sie können MyResourceDictionary instanziieren, indem Sie Sie zwischen einem Paar Resources Eigenschaften Element Tags, z. b. in einem ContentPage, einfügen:You can instantiate MyResourceDictionary by putting it between a pair of Resources property-element tags, for example, in a ContentPage:

<ContentPage ...>
    <ContentPage.Resources>
        <local:MyResourceDictionary />
    </ContentPage.Resources>
    ...
</ContentPage>

Eine Instanz von MyResourceDictionary ist auf die Resources-Eigenschaft des ContentPage-Objekts festgelegt.An instance of MyResourceDictionary is set to the Resources property of the ContentPage object.

Bei diesem Ansatz gelten jedoch einige Einschränkungen: die Resources-Eigenschaft des ContentPage verweist nur auf diese ResourceDictionary.However, this approach has some limitations: The Resources property of the ContentPage references only this one ResourceDictionary. In den meisten Fällen möchten Sie auch andere ResourceDictionary Instanzen und möglicherweise andere Ressourcen einschließen.In most cases, you want the option of including other ResourceDictionary instances and perhaps other resources as well.

Diese Aufgabe erfordert zusammengeführte Ressourcenwörterbücher.This task requires merged resource dictionaries.

Zusammengeführte Ressourcen VerzeichnisseMerged resource dictionaries

Zusammengeführte Ressourcen Wörterbücher kombinieren ein oder mehrere ResourceDictionary Objekte in einem anderen ResourceDictionary.Merged resource dictionaries combine one or more ResourceDictionary objects into another ResourceDictionary.

Lokale Ressourcen Wörterbücher zusammenführenMerge local resource dictionaries

Eine lokale ResourceDictionary kann in einer anderen ResourceDictionary zusammengeführt werden, indem die Eigenschaft Source auf den Dateinamen der XAML-Datei mit den Ressourcen festgelegt wird:A local ResourceDictionary can be merged into another ResourceDictionary by setting the Source property to the filename of the XAML file with the resources:

<ContentPage ...>
    <ContentPage.Resources>
        <!-- Add more resources here -->
        <ResourceDictionary Source="MyResourceDictionary.xaml" />
        <!-- Add more resources here -->
    </ContentPage.Resources>
    ...
</ContentPage>

Mit dieser Syntax wird die MyResourceDictionary-Klasse nicht instanziiert.This syntax does not instantiate the MyResourceDictionary class. Stattdessen verweist es auf die XAML-Datei.Instead, it references the XAML file. Wenn die Source -Eigenschaft festgelegt wird, ist aus diesem Grund keine Code Behind-Datei erforderlich, und das x:Class-Attribut kann aus dem Stammtag der myresourcedictionary. XAML -Datei entfernt werden.For that reason, when setting the Source property, a code-behind file isn't required, and the x:Class attribute can be removed from the root tag of the MyResourceDictionary.xaml file. Beim Zusammenführen von Ressourcen Wörterbüchern mithilfe dieses Ansatzes instanziiert xamarin. Forms die ResourceDictionary, sodass die äußeren ResourceDictionary Tags nicht erforderlich sind.In addition, when merging resource dictionaries using this approach, Xamarin.Forms will automatically instantiate the ResourceDictionary, hence the outer ResourceDictionary tags are not required.

Wichtig

Die Source -Eigenschaft kann nur aus XAML festgelegt werden.The Source property can only be set from XAML.

Ressourcen Wörterbücher aus anderen AssemblysMerge resource dictionaries from other assemblies

Eine ResourceDictionary kann auch in einem anderen ResourceDictionary zusammengeführt werden, indem Sie Sie der MergedDictionaries -Eigenschaft der ResourceDictionaryhinzufügen.A ResourceDictionary can also be merged into another ResourceDictionary by adding it into the MergedDictionaries property of the ResourceDictionary. Diese Technik ermöglicht das Zusammenführen von Ressourcen Wörterbüchern, unabhängig von der Assembly, in der Sie sich befinden.This technique allows resource dictionaries to be merged, regardless of the assembly in which they reside.

Wichtig

Die ResourceDictionary -Klasse definiert auch eine MergedWith -Eigenschaft.The ResourceDictionary class also defines a MergedWith property. Diese Eigenschaft ist jedoch veraltet und sollte nicht mehr verwendet werden.However, this property has been deprecated and should no longer be used.

Im folgenden Codebeispiel wird gezeigt, MyResourceDictionary der MergedDictionaries Auflistung eines ResourceDictionaryauf Seitenebene hinzugefügt wird:The following code example shows MyResourceDictionary being added to the MergedDictionaries collection of a page level ResourceDictionary:

<ContentPage ...
             xmlns:local="clr-namespace:ResourceDictionaryDemo">
    <ContentPage.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <local:MyResourceDictionary />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </ContentPage.Resources>
    ...
</ContentPage>

Dieses Beispiel zeigt eine Instanz von MyResourceDictionary, die sich in derselben Assembly befindet und der ResourceDictionaryhinzugefügt wird.This example shows an instance of MyResourceDictionary, which resides in the same assembly, being added to the ResourceDictionary. Außerdem können Sie Ressourcen Wörterbücher aus anderen Assemblys, anderen ResourceDictionary Objekten innerhalb der MergedDictionaries Eigenschaften-Element-Tags und anderen Ressourcen außerhalb der folgenden Tags hinzufügen:In addition, you can also add resource dictionaries from other assemblies, other ResourceDictionary objects within the MergedDictionaries property-element tags, and other resources outside of those tags:

<ContentPage ...
             xmlns:local="clr-namespace:ResourceDictionaryDemo"
             xmlns:theme="clr-namespace:MyThemes;assembly=MyThemes">
    <ContentPage.Resources>
        <ResourceDictionary>
            <!-- Add more resources here -->
            <ResourceDictionary.MergedDictionaries>
                <!-- Add more resource dictionaries here -->
                <local:MyResourceDictionary />
                <theme:LightTheme />
                <!-- Add more resource dictionaries here -->
            </ResourceDictionary.MergedDictionaries>
            <!-- Add more resources here -->
        </ResourceDictionary>
    </ContentPage.Resources>
    ...
</ContentPage>

Wenn Sie eine ResourceDictionary in einer externen Assembly platzieren, stellen Sie sicher, dass die Buildaktion auf EmbeddedResourcefestgelegt ist.When placing a ResourceDictionary in an external assembly, ensure that its build action is set to EmbeddedResource. Außerdem müssen Sie sicherstellen, dass Sie über eine Code-Behind-Datei verfügt.In addition, ensure that it has a code-behind file.

Wichtig

Es darf nur ein MergedDictionaries Property-Element-Tag in einer ResourceDictionaryvorhanden sein, aber Sie können dort beliebig viele ResourceDictionary Objekte ablegen.There can be only one MergedDictionaries property-element tag in a ResourceDictionary, but you can put as many ResourceDictionary objects in there as you want.

Wenn zusammengeführte ResourceDictionary Ressourcen identische x:Key Attributwerte gemeinsam verwenden, verwendet xamarin. Forms die folgende Ressourcen Rangfolge:When merged ResourceDictionary resources share identical x:Key attribute values, Xamarin.Forms uses the following resource precedence:

  1. Die Ressourcen, die lokal auf das Ressourcenverzeichnis.The resources local to the resource dictionary.
  2. Die Ressourcen in den Ressourcen Wörterbüchern, die über die MergedDictionaries Auflistung zusammengeführt wurden, werden in umgekehrter Reihenfolge in der MergedDictionaries-Eigenschaft aufgelistet.The resources contained in the resource dictionaries that were merged via the MergedDictionaries collection, in the reverse order they are listed in the MergedDictionaries property.

Hinweis

Ressourcenverzeichnisse suchen kann eine rechenintensive Aufgabe sein, wenn eine Anwendung mehrere enthält große Ressourcenwörterbücher.Searching resource dictionaries can be a computationally intensive task if an application contains multiple, large resource dictionaries. Um zu vermeiden, unnötige Suchläufe, sollten Sie daher sicherstellen, dass jede Seite in einer Anwendung nur Ressourcenverzeichnisse verwendet, die auf der Seite geeignet sind.Therefore, to avoid unnecessary searching, you should ensure that each page in an application only uses resource dictionaries that are appropriate to the page.

Auf Channel 9 und auf YouTube finden Sie weitere Videos zu Xamarin.Find more Xamarin videos on Channel 9 and YouTube.