Premiers pas avec Xamarin.Forms Options de disposition

1. Options de mise en page

Lorsqu'il s'agit de concevoir et d'agencer les écrans de votre application, vous avez deux options principales: écrire du code ou utiliser XAML. Si vous avez déjà effectué un développement WPF (Windows Presentation Foundation) ou Silverlight, vous connaissez probablement déjà XAML. XAML est le Langage de balisage d'applications eXtensible qui a été créé pour aider à définir l'apparence d'une application sans avoir à tout gérer en code. Xamarin.Forms fonctionne avec les deux options. Ce sera finalement à vous de décider quelle option vous préférez.

Il est important de noter que le XAML utilisé pour Xamarin.Forms n'est pas compatible avec d'autres formes d'outils XAML et XAML..

Option 1: Utiliser le code

Si vous êtes le type de personne qui aime figurer dans le code et qui ne souhaite rien avoir à faire avec une sorte de balisage, ni avec un concepteur, vous serez probablement très à l'aise avec cette option. Vous instanciez par programmation différents types de Vue objets et les ajouter directement à un Page ou à un Disposition sur un Page. Voici un exemple simple de création d’un SimplePage classe, instanciant quelques Vue objets, et en les ajoutant à la Page à travers un StackLayout objet.

Classe publique SamplePage: ContentPage public SamplePage () Padding = new Thickness (20); var label = new Label "Text =" Je suis une simple page ", BackgroundColor = Color.Blue, Font = Font.SystemFontOfSize (30), WidthRequest = 150, HeightRequest = 40 var button = new Button Text = "J'ai un bouton", BackgroundColor = Color.Red, Font = Font.SystemFontOfSize (20), WidthRequest = 200, HeightRequest = 200; var entry = nouvelle entrée Placeholder = "J'ai une zone de saisie", BackgroundColor = Color.Green, WidthRequest = 200, HeightRequest = 150; Contenu = new StackLayout Spacing = 10, Children = button, entry, label; 

Comme vous pouvez le voir, le Vue les objets ont en commun un certain nombre de propriétés, que vous pouvez utiliser pour définir le texte, les couleurs, l’espacement, la hauteur, la largeur, etc. Il suffit maintenant de modifier le GetMainPage méthode dans le App classe pour renvoyer une nouvelle instance du Page d'exemple classe, et c'est parti.

Personne ne m'a jamais accusé d'être un concepteur, mais il est aussi facile de créer des pages de base en code.

Option 2: utilisation de XAML

Si vous préférez séparer l'apparence de votre application de la logique et de la mise en œuvre, XAML est peut-être la solution. XAML vous permet de créer la mise en page complète de votre application dans un format XML spécialisé que Xamarin peut convertir en pages, en dispositions, en vues et en cellules et les afficher à l'utilisateur. Si vous n'avez jamais utilisé XAML auparavant, il faudra peut-être un peu de temps pour s'y habituer. Cependant, une fois que vous maîtrisez la situation, cela peut en fait être très agréable.

Pour utiliser XAML en combinaison avec Xamarin.Forms, vous devez créer votre projet à l’aide de la Application vierge (Xamarin.Forms Portable) modèle de sorte que tout le code Xamarin.Forms puisse être séparé en son propre dll.

Dans l'exemple de code de la section précédente, vous avez créé un très simple Contenu de la page classe en code. Pour créer le même Contenu de la page en utilisant XAML, cliquez avec le bouton droit sur le projet PCL et sélectionnez Ajouter> Nouvel élément. Du Ajoute un nouvel objet boîte de dialogue, sélectionnez le Formulaires Xaml Page template et remplacez le contenu par défaut par ce qui suit:

   

Si vous exécutez votre application, vous devriez voir le même écran que dans l'exemple de code. le PageDisposition, et Vue les types correspondent aux éléments XML et les propriétés sont les attributs de l'élément. Vous êtes libre d'utiliser l'une ou l'autre option pour créer des interfaces utilisateur multi-plateformes entièrement personnalisables..

2. Flexibilité grâce à la liaison de données

Vous pouvez créer des applications où vous créez le Vue objets pour votre Page objets et définir explicitement leurs propriétés, mais cela devient rapidement encombrant. Lorsque vous définissez explicitement des propriétés dans votre code XAML, vous ne pouvez plus réutiliser ce code XAML. Page pour toute autre chose. En d'autres termes, vous devez créer de nouvelles pages XAML pour chaque variante dont vous avez besoin. Qui a le temps pour cela?

Ce ne serait pas bien si vous pouviez créer des pages XAML réutilisables sans code d'interface utilisateur personnalisé et tout garder séparés logiquement? Bien sûr. Bienvenue sur MVVM.

4. Model-View-ViewModel

Model-View-ViewModel est un motif architectural créé avec XAML à l’esprit. À la base, il partage le concept de base d'autres modèles architecturaux tels que MVP et MVC. Il a été conçu pour séparer les données, la couche modèle, de la présentation, la couche vue. Le conduit entre les deux est le ViewModel. Le modèle de vue est une classe qui facilite la communication entre le modèle et les couches de vue via un mécanisme appelé liaison de données. La liaison de données est au cœur du modèle MVVM et est effectuée via XAML lui-même. Regardons un exemple.

5. Créer un exemple d'application

Commencez par créer une nouvelle application Xamarin.Forms en sélectionnant le Application vierge (Xamarin.Forms Portable) modèle de projet et en lui donnant le nom de MyRecipeBox.

Comme vous l'avez probablement deviné, ce sera la base d'une application de base pouvant stocker des recettes. Commençons par créer un modèle de base de l'application, une recette.

dans le MyRecipeBox projet, créez un nouveau dossier et nommez-le Des modèles. Ce n'est pas une obligation, cela ajoute simplement une organisation au projet, qui aide toujours à mesure qu'il s'agrandit. dans le Des modèles dossier, ajoutez une nouvelle classe et nommez-la Recette. Remplacez l'implémentation par défaut par ce qui suit:

Classe publique Recipe chaîne publique Nom get; ensemble;  chaîne publique Description get; ensemble;  public TimeSpan PrepTime get; ensemble;  public TimeSpan CookingTime get; ensemble;  liste publique Directions get; ensemble; 

Maintenant que vous avez une classe de modèle de base, vous pouvez créer un modèle de vue pour celle-ci. Pensez à un modèle de vue en tant que classe contenant les parties d'un modèle qui doivent être affichées et avec lesquelles vous devez interagir sur un écran. Pour que les choses restent simples, nous allons nous concentrer sur les quatre principales propriétés..

Créer un nouveau dossier dans le MyRecipeBox projet et nommez-le ViewModels. dans le ViewModels dossier, créez une nouvelle classe et nommez-la RecipeViewModel. Lors de l’adoption du modèle MVVM dans .NET, les modèles de vue sont généralement caractérisés par le fait qu’ils implémentent la INotifyPropertyChanged interface. Cette interface est ce qui permet aux autres parties du code de s'abonner aux événements et d'activer la liaison de données. Remplacer l'implémentation par défaut du RecipeViewModel classe avec les éléments suivants:

Classe publique RecipeViewModel: INotifyPropertyChanged recette privée _recipe; événement public PropertyChangedEventHandler PropertyChanged; public RecipeViewModel (recette de recette) _recipe = recipe; Directions = new ObservableCollection(_recipe.Directions);  public ObservableCollection Directions get; ensemble;  chaîne publique Nom get return _recipe! = null? _recipe.Name: null;  set if (_recipe! = null) _recipe.Name = valeur; if (PropertyChanged! = null) PropertyChanged (this, nouveau PropertyChangedEventArgs ("Nom"));  chaîne publique Description get return _recipe! = null? _recipe.Description: null;  set if (_recipe! = null) _recipe.Description = valeur; if (PropertyChanged! = null) PropertyChanged (new, PropertyChangedEventArgs ("Description"));  chaîne publique PrepTime get return _recipe! = null? _recipe.PrepTime.ToString (): "Aucun";  set if (_recipe! = null) _recipe.PrepTime = TimeSpan.Parse (valeur); if (PropertyChanged! = null) PropertyChanged (this, nouveau PropertyChangedEventArgs ("PrepTime"));  chaîne publique CookingTime get return _recipe! = null? _recipe.CookingTime.ToString (): "Aucun";  set if (_recipe! = null) _recipe.CookingTime = TimeSpan.Parse (valeur); if (PropertyChanged! = null) PropertyChanged (this, nouveau PropertyChangedEventArgs ("CookingTime")); 

Vous avez peut-être remarqué que le RecipeViewModel met en œuvre le INotifyPropertyChanged interface. Si vous creusez plus en profondeur dans cette interface, vous verrez qu'elle contient une propriété qui doit être implémentée..

interface publique INotifyPropertyChanged événement PropertyChangedEventHandler PropertyChanged; 

le RecipleViewModel la classe prend dans une instance du Recette classe et n'expose ensuite que quatre de ses propriétés. Les getters associés à ces propriétés renvoient simplement les données dans la Recette exemple lui-même. Les setters, d’autre part, vérifient si PropertyChanged n'est pas nulPropertyChanged sera nul s'il n'y a pas d'abonné à cet événement. Dans ce cas, rien ne se passe. Si PropertyChanged n'est pas nul, puis l'événement est appelé et chaque abonné de l'événement reçoit l'information que ce modèle de vue a changé.

Dans le modèle MVVM, l'abonné à ces événements est généralement la vue décrite par le code XAML, permettant à l'interface utilisateur de se mettre à jour si les modèles sous-jacents ont changé..

Il est temps de créer une page qui montre à l'utilisateur les données de recette et exploite la liaison de données pour mettre à jour l'interface utilisateur. Commencez par créer un Des vues dossier dans le MyRecipeBox projet. dans le Des vues dossier, ajouter un nouveau Formulaires Xaml Page et nommez-le RecipeSummaryPage.

Remplacez le XAML par défaut dans le fichier par ce qui suit:

    

Comme vous pouvez le constater, la liaison est créée en plaçant du texte mis en forme à l'endroit où vous souhaitez que les données liées apparaissent. La syntaxe pour accomplir cela est "Binding xxxxx", où xxxxx est le nom de la propriété à laquelle vous souhaitez lier. Enfin, vous vous demandez peut-être comment vous associez le modèle de vue que vous avez créé à cette vue..

Si vous cliquez sur la petite flèche à côté de la RecipeSummaryPage.xaml fichier, vous devriez voir un autre fichier apparaître, RecipleSummaryPage.xaml.cs. C'est le code derrière le fichier qui contient le code C # pour exécuter cette page. Vous devez modifier le constructeur de cette classe pour qu'il ressemble à ceci:

public RecipeSummaryPage (RecipeViewModel recipeViewModel) InitializeComponent (); this.BindingContext = recipeViewModel; 

le BindingContext propriété est l'endroit où vous devez affecter le modèle de vue pour créer la liaison susmentionnée. Pour ce faire, passez une instance de votre RecipeViewModel dans le constructeur.

Pour voir apparaître les fruits de notre travail à l'écran, vous devez effectuer un petit changement pour que cela fonctionne. dans le App.cs fichier, dans le MyRecipeBox projet, mettez à jour le GetMainPage méthode comme indiqué ci-dessous.

page statique publique GetMainPage () var recipe = nouvelle recette Name = "pain grillé", Description = "c'est du pain grillé, vous plaisantez?", PrepTime = nouveau TimeSpan (0, 0, 15), CookingTime = nouveau TimeSpan (0, 2, 0), Directions = nouvelle liste"Prenez du pain", "Mettez du pain dans le grille-pain", "Mangez du pain grillé"; renvoyer nouvelle RecipeSummaryPage (nouvelle RecipeViewModel (recette)); 

Le résultat devrait ressembler aux captures d'écran suivantes.

Dans la prochaine et dernière étape, nous allons créer et afficher une liste de Recette objets sur lesquels l'utilisateur peut cliquer pour les amener à une page de détail. Commençons par créer un nouveau modèle de vue contenant une liste de Recette objets. Ajouter une nouvelle classe à la ViewModels dossier et nommez-le RecipeListViewModel. Sa mise en œuvre ressemble à ceci:

Classe publique RecipeListViewModel public ObservableCollection Recettes get; ensemble;  public RecipeListViewModel () Recipes = new ObservableCollection(); Recipes.Add (new Recipe Name = "Toast", Description = "Vous plaisantez? C'est du pain grillé.", CookingTime = new TimeSpan (0, 2, 0), PrepTime = new TimeSpan (0, 0, 15), Directions = nouvelle liste "Ramassez le pain", "Mettez la grille dans le grille-pain", "Mangez le pain grillé"); Recipes.Add (nouvelle recette Name = "Céréale", Description = "Vous savez, le petit-déjeuner.", CookingTime = TimeSpan.Zero, PrepTime = nouveau TimeSpan (0, 1, 0), Directions = new List "Mettez les céréales dans un bol", "Mettez le lait dans un bol", "Mettez une cuillère dans un bol", "Mettez une cuillère dans la bouche"); Recipes.Add (nouvelle recette Name = "Sandwich", Description = "Pain et autres. Miam!", CookingTime = TimeSpan.Zero, PrepTime = nouveau TimeSpan (0, 5, 0), Directions = new List "Obtenez 2 tranches de pain", "Mettez le fromage entre les tranches de pain", "Mettez le jambon entre les tranches de pain", "Amusez-vous"); 

Vous avez peut-être remarqué que nous avons codé les recettes dans le RecipeListViewModel classe. Dans une application réelle, les recettes seraient extraites d'un service Web ou d'une base de données..

Créez une nouvelle page pour afficher la liste des recettes. dans le Des vues dossier, créer un nouveau Formulaire Xaml Page et nommer celui-ci RecipleListPage. Remplacez son contenu par ce qui suit:

         

Ce XAML est assez similaire à l'exemple précédent. Cette fois, cependant, vous n’avez qu’une vue en liste sur la page. Lors de l'utilisation de la liaison de données dans un ListView, vous devez creuser un peu plus profondément pour faire la liaison réelle. Tout d’abord, vous liez la liste complète au ItemsSource propriété duListView et vous devez ensuite définir le Modèle et DataTemplate du ListView être un TextCell et lier ça TextCell à la propriété individuelle de la Recette par exemple, vous souhaitez afficher. C’est ce qui rend les noms de recettes à l’écran.

Vous pouvez aussi voir qu'il y a un prénom associé au ListViewrecetteList, qui sera utile un peu plus tard, ainsi qu’un gestionnaire d’événements. Dans ce cas, lorsqu'un utilisateur appuie sur un élément de la ListView, la ItemTapped l'événement est déclenché. Vous êtes maintenant abonné à cet événement et utiliserez une méthode nommée OnItemSelected pour le gérer.

Dans la prochaine étape, nous devons faire un peu de câblage dans le RecipeListPage.xaml.cs fichier pour définir leBindingContext de notre nouvelle page ainsi que la mise en œuvre de la OnItemSelected gestionnaire d'événements.

classe partielle publique RecipeListPage public RecipeListPage () InitializeComponent (); this.BindingContext = new RecipeListViewModel ();  public void OnItemSelected (expéditeur d'objet, args ItemTappedEventArgs) var recipe = args.Item as Recipe; if (recipe == null) return; Navigation.PushAsync (nouvelle RecipeSummaryPage (nouvelle RecipeViewModel (recette))); // Réinitialiser l'élément sélectionné recipeList.SelectedItem = null; 

le BindingContext la propriété sera simplement définie sur une nouvelle instance du RecipleListViewModel que vous avez créé plus tôt. La méthode du gestionnaire d'événements est un peu différente. Tout d'abord, vous devez vérifier que l'élément sélectionné est une recette, ce qui est accompli dans les lignes suivantes:

var recipe = args.Item as Recipe; if (recipe == null) return;

Si l'élément sélectionné est un Recette objet, alors vous utilisez le La navigation propriété pour ajouter une nouvelle instance du RecipleSummaryPage au courant NavigationView. Enfin, vous devez vous assurer qu'aucun élément de la liste n'est actuellement sélectionné..

Navigation.PushAsync (nouvelle RecipeSummaryPage (nouvelle RecipeViewModel (recette))); // Réinitialiser l'élément sélectionné recipeList.SelectedItem = null;

Accéder au ListView se fait à travers le prénom qui lui a été attribué plus tôt. Vous pouvez avoir accès à tout Vue sur la page en assignant un prénom auVue et en se référant par nom dans le code.

Le dernier changement que nous devons faire est la mise à jour de la GetMainPage méthode dans le App.cs fichier. comme indiqué ci-dessous:

page statique publique GetMainPage () retourne la nouvelle NavigationPage (nouvelle RecipeListPage ()); 

Vous retournez une nouvelle instance du NavigationPage classe en tant que votre page principale et définir sa page racine à une nouvelle instance du RecipleListPage classe. Maintenant que tout est câblé, vous pouvez exécuter votre application sur les trois plates-formes et voir à peu près ce qui suit:

Appuyez sur l'une des lignes de la liste pour afficher la page récapitulative de recette correspondante, comme vous l'avez déjà vu..

Conclusion

Vous avez maintenant vu les différentes options pour la présentation de votre application à l'aide de Xamarin.Forms. Vous devez être à l'aise pour créer des applications de base pouvant s'exécuter sur les principales plates-formes mobiles à l'aide d'une base de code unique pour la logique métier et l'interface utilisateur de l'application. Une fois que vous aurez passé du temps avec Xamarin.Forms, l'étape suivante consistera à personnaliser l'interface utilisateur de l'application et à ajouter de nouveaux contrôles. Mais c'est pour un autre jour.

Prochaine étape: regarder le parcours

Si vous souhaitez en savoir plus sur Xamarin, consultez notre cours Création d'applications multi-plateformes avec C # dans Xamarin. 

Dans ce cours, vous apprendrez à créer une application multiplate-forme à partir d'une base de code unique qui s'exécutera sur trois plates-formes distinctes: iOS, Android et Windows Phone 8. Vous pensez que cela ne peut être fait? Dans peu de temps, vous le ferez vous-même. Mettons-nous au travail.

Vous pouvez prendre le tout de suite avec un complètement libre Essai de 14 jours d'un abonnement Tuts +. Jetez un coup d'œil à nos options d'abonnement pour commencer ou, si ce cours vous intéresse, vous pouvez l'acheter à l'unité pour 15 $! Voici un aperçu pour vous aider à démarrer: