Xamarin Forms FR
Xamarin Forms FR
Xamarin Forms FR
Forms
#xamarin.fo
rms
Table des matières
À propos 1
Remarques 2
Versions 2
Examples 3
Xamarin.Forms 4
Remarques 8
Examples 8
Implémentation Android 10
Obtenir les numéros de version du système d’exploitation et d’appareils - Android & iOS - 12
Examples 15
Ajustements Idiom 15
Ajustements de la plateforme 15
Examples 18
DisplayAlert 18
Examples 20
Remarques 22
Examples 22
Créer une API à l'aide d'une base de données SQL et implémenter des formulaires Xamarin, 22
Remarques 23
Examples 23
Importer CarouselView 23
Les bases 24
DataTemplates 24
Examples 26
EntryCell 26
SwitchCell 26
TextCell 27
ImageCell 28
ViewCell 29
Remarques 31
Examples 31
Remarques 34
Examples 34
contact_picker.cs 34
MyPage.cs 34
ChooseContactPicker.cs 35
ChooseContactActivity.cs 35
MainActivity.cs 37
ChooseContactRenderer.cs 37
Examples 40
Créez un contrôle d'entrée personnalisé Xamarin Forms (aucun élément natif requis) 40
Introduction 46
Examples 46
Examples 54
Examples 56
Le cycle de vie de Xamarin.Forms n'est pas le cycle de vie réel d'une application, mais un 56
Examples 58
Multi déclencheurs 59
Examples 61
Interface 61
Code partagé 62
Implémentation Android 63
Introduction 65
Examples 65
Examples 70
Touchez le geste 70
Examples 71
Événement gestuel 71
Examples 73
Examples 76
Remarques 79
Exceptions possibles 79
Introduction 82
Examples 82
Exemple simple 82
Arguments de passage 83
Se désabonner 83
Examples 84
A propos d'Akavache 84
Exemple simple 84
Examples 86
ContentPresenter 86
ContentView 86
Cadre 87
ScrollView 88
TemplatedView 90
AbsoluteLayout 90
la grille 93
Disposition relative 95
StackLayout 96
Remarques 100
Examples 100
Page avec une étiquette simple au milieu 100
Examples 105
Page1.xaml 108
Page1.xaml.cs 108
Page2.xaml 108
Page2.xaml.cs 108
Page3.xaml 109
Page3.xaml.cs 109
Remarques 112
Examples 112
Remarques 116
Examples 116
Examples 124
Examples 126
Examples 128
TabbedPage 128
MasterDetailPage 130
Remarques 132
Examples 132
Chapitre 34: Pourquoi utiliser les formulaires Xamarin et quand utiliser les formulaires X 135
Remarques 135
Examples 135
Pourquoi utiliser les formulaires Xamarin et quand utiliser les formulaires Xamarin 135
Examples 137
Étiquette arrondie avec un moteur de rendu personnalisé pour Frame (parties PCL et iOS) 143
Remarques 147
Examples 147
Accéder à la caméra et à la galerie. 147
Examples 148
Remarques 155
Examples 155
Spécflow simple pour tester les commandes et la navigation avec NUnit Test Runner 155
Usage: 155
Examples 159
Travailler avec des bases de données locales en utilisant xamarin.forms dans visual studio 161
Remarques 172
Examples 172
Introduction 186
Examples 186
Examples 187
Bouton 187
Entrée 189
Éditeur 190
Image 191
Étiquette 192
Examples 194
Crédits 206
À propos
You can share this PDF with anyone you feel could benefit from it, downloaded the latest version
from: xamarin-forms
It is an unofficial and free Xamarin.Forms ebook created for educational purposes. All the content
is extracted from Stack Overflow Documentation, which is written by many hardworking individuals
at Stack Overflow. It is neither affiliated with Stack Overflow nor official Xamarin.Forms.
The content is released under Creative Commons BY-SA, and the list of contributors to each
chapter are provided in the credits section at the end of this book. Images may be copyright of
their respective owners unless otherwise specified. All trademarks and registered trademarks are
the property of their respective company owners.
Use the content presented in this book at your own risk; it is not guaranteed to be correct nor
accurate, please send your feedback and corrections to info@zzzprojects.com
https://riptutorial.com/fr/home 1
Chapitre 1: Démarrer avec Xamarin.Forms
Remarques
Xamarin.Forms permet de créer des applications iOS, Android et Windows avec de grandes
quantités de code partagé, notamment du code d'interface utilisateur ou du balisage d'interface
utilisateur XAML. Les pages et les vues des applications sont mappées aux contrôles natifs de
chaque plate-forme, mais peuvent être personnalisées pour fournir une interface utilisateur
spécifique à la plate-forme ou pour accéder à des fonctionnalités spécifiques à la plate-forme.
Versions
2.3.1 2016-08-03
2.3.0-correctif1 2016-06-29
2.3.0 2016-06-16
2.2.0-correctif1 2016-05-30
2.2.0 2016-04-27
2.1.0 2016-03-13
2.0.1 2016-01-20
2.0.0 2015-11-17
1.5.1 2016-10-20
1.5.0 2016-09-25
1.4.4 2015-07-27
1.4.3 2015-06-30
1.4.2 2015-04-21
1.4.1 2015-03-30
1.4.0 2015-03-09
1.3.5 2015-03-02
1.3.4 2015-02-17
https://riptutorial.com/fr/home 2
Version Date de sortie
1.3.3 2015-02-09
1.3.2 2015-02-03
1.3.1 2015-01-04
1.3.0 2014-12-24
1.2.3 2014-10-02
1.2.2 2014-07-30
1.2.1 2014-07-14
1.2.0 2014-07-11
1.1.1 2014-06-19
1.1.0 2014-06-12
1.0.1 2014-06-04
Examples
Installation (Visual Studio)
Xamarin.Forms est une abstraction d'interface utilisateur basée sur une plate-forme d'interface
utilisateur native, qui permet aux développeurs de créer facilement des interfaces utilisateur
pouvant être partagées entre Android, iOS, Windows et Windows Phone. Les interfaces utilisateur
sont rendues à l'aide des contrôles natifs de la plate-forme cible, permettant aux applications
Xamarin.Forms de conserver l'apparence appropriée pour chaque plate-forme.
Si vous avez déjà installé la dernière version de Visual Studio, accédez au Panneau de
configuration> Programmes et fonctionnalités, cliquez avec le bouton droit sur Visual Studio, puis
cliquez sur Modifier. Lorsque le programme d'installation s'ouvre, cliquez sur Modifier et
sélectionnez les outils de développement mobiles multiplates-formes:
https://riptutorial.com/fr/home 3
Vous pouvez également choisir d’installer le SDK Android:
Décochez-la si le SDK est déjà installé. Vous pourrez configurer Xamarin pour utiliser le SDK
Android existant plus tard.
Xamarin.Forms
Xamarin.Forms est un ensemble de bibliothèques pour votre bibliothèque Portable Class et vos
assemblys natifs. La bibliothèque Xamarin.Forms est disponible sous forme de package NuGet.
Pour l'ajouter à votre projet, utilisez simplement la commande Install-Package standard de la
console du gestionnaire de packages:
Install-Package Xamarin.Forms
pour tous vos assemblages initiaux (par exemple MyProject, MyProject.Droid et MyProject.iOS).
La manière la plus simple de commencer avec Xamarin.Forms est de créer un projet vide dans
Visual Studio:
https://riptutorial.com/fr/home 4
Comme vous pouvez le voir, deux options sont disponibles pour créer l'application vide: Portable
et Partagé. Je vous recommande de commencer avec Portable un parce que c'est le plus
couramment utilisé dans le monde réel (différences et plus d'explications à ajouter).
Après avoir créé le projet, assurez-vous d'utiliser la dernière version de Xamarin.Forms car votre
modèle initial peut contenir l'ancien. Utilisez l'option Console du gestionnaire de paquets ou Gérer
les packages NuGet pour effectuer la mise à niveau vers la dernière version de Xamarin.Form
(n'oubliez pas qu'il s'agit simplement d'un package NuGet).
Alors que les modèles Visual Studio Xamarin.Forms créeront un projet de plate-forme iOS pour
vous, vous devrez connecter Xamarin à un hôte de génération Mac pour pouvoir exécuter ces
projets sur le simulateur iOS ou les périphériques physiques.
Après l'installation réussie de Xamarin comme décrit dans le premier exemple, il est temps de
lancer le premier exemple d'application.
https://riptutorial.com/fr/home 5
Nommez l'application "Hello World" et sélectionnez l'emplacement pour créer le projet et cliquez
sur OK. Cela créera une solution pour vous qui contient trois projets:
1. HelloWorld (c'est là que se trouve votre logique et vos vues, c’est-à-dire le projet portable)
2. HelloWorld.Droid (le projet Android)
3. HelloWorld.iOS (le projet iOS)
https://riptutorial.com/fr/home 6
using Xamarin.Forms;
namespace Hello_World
{
public class App : Application
{
public App()
{
// The root page of your application
MainPage = new ContentPage
{
Content = new StackLayout
{
VerticalOptions = LayoutOptions.Center,
Children = {
new Label {
HorizontalTextAlignment = TextAlignment.Center,
Text = "Welcome to Xamarin Forms!"
}
}
}
};
}
protected override void OnStart()
{
// Handle when your app starts
}
protected override void OnSleep()
{
// Handle when your app sleeps
}
protected override void OnResume()
{
// Handle when your app resumes
}
}
}
https://riptutorial.com/fr/home 7
Chapitre 2: Accès aux fonctionnalités natives
avec DependencyService
Remarques
Si vous ne voulez pas que votre code se brise lorsqu'aucune implémentation n'est trouvée,
vérifiez d'abord le DependencyService s'il dispose d'une implémentation disponible.
Vous pouvez le faire par une simple vérification si elle n'est pas null .
if (speaker != null)
{
speaker.Speak("Ready for action!");
}
Si vous ne le faites pas et qu'aucune implémentation n'est trouvée à l'exécution, votre code
générera une exception.
Examples
Mise en œuvre de la synthèse vocale
https://riptutorial.com/fr/home 8
Dans notre code partagé, nous définissons une interface qui est enregistrée avec
DependencyService . C'est là que nous ferons appel à nous. Définir une interface comme ci-
dessous.
Maintenant, dans chaque plate-forme spécifique, nous devons créer une implémentation de cette
interface. Commençons par l'implémentation iOS.
https://riptutorial.com/fr/home 9
{
public TextToSpeechImplementation () {}
speechSynthesizer.SpeakUtterance (speechUtterance);
}
}
Dans l'exemple de code ci-dessus, vous remarquez qu'il existe un code spécifique à iOS. Comme
les types tels que AVSpeechSynthesizer . Celles-ci ne fonctionneraient pas dans le code partagé.
Pour enregistrer cette implémentation avec Xamarin DependencyService ajoutez cet attribut au-
dessus de la déclaration d'espace de noms.
using AVFoundation;
using DependencyServiceSample.iOS;//enables registration outside of namespace
Maintenant, lorsque vous faites un appel comme celui-ci dans votre code partagé, la bonne
implémentation de la plate-forme sur laquelle vous exécutez votre application est injectée.
Implémentation Android
L'implémentation Android de ce code ressemblerait à celle ci-dessous.
using Android.Speech.Tts;
using Xamarin.Forms;
using System.Collections.Generic;
using DependencyServiceSample.Droid;
public TextToSpeechImplementation () {}
https://riptutorial.com/fr/home 10
public void Speak (string text)
{
var ctx = Forms.Context; // useful for many Android SDK features
toSpeak = text;
if (speaker == null) {
speaker = new TextToSpeech (ctx, this);
} else {
var p = new Dictionary<string,string> ();
speaker.Speak (toSpeak, QueueMode.Flush, p);
}
}
using Android.Speech.Tts;
using Xamarin.Forms;
using System.Collections.Generic;
using DependencyServiceSample.Droid;
mediaElement.SetSource(stream, stream.ContentType);
mediaElement.Play();
await synth.SynthesizeTextToStreamAsync(text);
}
}
https://riptutorial.com/fr/home 11
Et une fois de plus, n'oubliez pas de l'enregistrer.
using Windows.Media.SpeechSynthesis;
using Windows.UI.Xaml.Controls;
using DependencyServiceSample.WinPhone;//enables registration outside of namespace
Dans ce code, vous verrez une page qui pourrait être dans un projet Xamarin Forms. Il crée un
bouton qui appelle la méthode Speak() à l'aide de DependencyService .
public MainPage ()
{
var speak = new Button {
Text = "Hello, Forms !",
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
};
speak.Clicked += (sender, e) => {
DependencyService.Get<ITextToSpeech>().Speak("Hello from Xamarin Forms");
};
Content = speak;
}
Le résultat sera que lorsque l'application est exécutée et que le bouton est cliqué, le texte fourni
sera prononcé.
Tout cela sans avoir à faire des choses difficiles comme des conseils de compilation et autres.
Vous disposez désormais d'un moyen unique d'accéder aux fonctionnalités spécifiques à la
plateforme via un code indépendant de la plate-forme.
https://riptutorial.com/fr/home 12
/// On iOS, gets the <c>CFBundleVersion</c> number and on Android, gets the
<c>PackageInfo</c>'s <c>VersionName</c>, both of which are specified in their respective
project properties.
/// </summary>
/// <returns><c>string</c>, containing the build number.</returns>
string GetAppVersion();
/// <summary>
/// On iOS, gets the <c>UIDevice.CurrentDevice.SystemVersion</c> number and on Android,
gets the <c>Build.VERSION.Release</c>.
/// </summary>
/// <returns><c>string</c>, containing the OS version number.</returns>
string GetOsVersion();
}
Android:
[assembly: Dependency(typeof(NativeHelper_Android))]
namespace YourNamespace.Droid{
public class NativeHelper_Android : INativeHelper {
/// <summary>
/// See interface summary.
/// </summary>
public string GetAppVersion() {
Context context = Forms.Context;
return context.PackageManager.GetPackageInfo(context.PackageName, 0).VersionName;
}
/// <summary>
/// See interface summary.
/// </summary>
public string GetOsVersion() { return Build.VERSION.Release; }
}
}
iOS:
[assembly: Dependency(typeof(NativeHelper_iOS))]
namespace YourNamespace.iOS {
public class NativeHelper_iOS : INativeHelper {
/// <summary>
/// See interface summary.
/// </summary>
public string GetAppVersion() { return
Foundation.NSBundle.MainBundle.InfoDictionary[new
Foundation.NSString("CFBundleVersion")].ToString(); }
/// <summary>
/// See interface summary.
/// </summary>
public string GetOsVersion() { return UIDevice.CurrentDevice.SystemVersion; }
}
https://riptutorial.com/fr/home 13
}
if(helper != null) {
string osVersion = helper.GetOsVersion();
string appVersion = helper.GetBuildNumber()
}
}
https://riptutorial.com/fr/home 14
Chapitre 3: Ajustements visuels spécifiques à
la plate-forme
Examples
Ajustements Idiom
Des ajustements spécifiques à l'idiome peuvent être effectués à partir du code C #, par exemple
pour modifier l'orientation de la mise en page, que la vue soit affichée ou un téléphone ou une
tablette.
if (Device.Idiom == TargetIdiom.Phone)
{
this.panel.Orientation = StackOrientation.Vertical;
}
else
{
this.panel.Orientation = StackOrientation.Horizontal;
}
<StackLayout x:Name="panel">
<StackLayout.Orientation>
<OnIdiom x:TypeArguments="StackOrientation">
<OnIdiom.Phone>Vertical</OnIdiom.Phone>
<OnIdiom.Tablet>Horizontal</OnIdiom.Tablet>
</OnIdiom>
</StackLayout.Orientation>
</StackLayout>
Ajustements de la plateforme
Des ajustements peuvent être effectués pour des plates-formes spécifiques à partir du code C #,
par exemple pour modifier le remplissage de toutes les plates-formes ciblées.
if (Device.OS == TargetPlatform.iOS)
{
panel.Padding = new Thickness (10);
}
else
{
panel.Padding = new Thickness (20);
}
Une méthode d'assistance est également disponible pour les déclarations C # raccourcies:
https://riptutorial.com/fr/home 15
Ces fonctionnalités sont également disponibles directement à partir du code XAML:
<StackLayout x:Name="panel">
<StackLayout.Padding>
<OnPlatform x:TypeArguments="Thickness"
iOS="10"
Android="20" />
</StackLayout.Padding>
</StackLayout>
Lorsque vous travaillez avec XAML, l'utilisation d'un Style centralisé vous permet de mettre à jour
un ensemble de vues stylisées à partir d'un seul endroit. Tous les réglages de langue et de plate-
forme peuvent également être intégrés à vos styles.
<Style TargetType="StackLayout">
<Setter Property="Padding">
<Setter.Value>
<OnPlatform x:TypeArguments="Thickness"
iOS="10"
Android="20"/>
</Setter.Value>
</Setter>
</Style>
Vous pouvez créer des vues personnalisées pouvant être intégrées à votre page grâce à ces
outils de réglage.
Sélectionnez File > New > File... > Forms > Forms ContentView (Xaml) et créez une vue pour
chaque présentation spécifique: TabletHome.xaml et PhoneHome.xaml .
Sélectionnez ensuite File > New > File... > Forms > Forms ContentPage et créez un File > New >
File... > Forms > Forms ContentPage HomePage.cs contenant:
using Xamarin.Forms;
}
}
https://riptutorial.com/fr/home 16
Vous avez maintenant un HomePage qui crée une hiérarchie de vue différente pour Phone idiomes du
Phone et de la Tablet .
https://riptutorial.com/fr/home 17
Chapitre 4: Alerte d'affichage
Examples
DisplayAlert
Une boîte d'alerte peut être Xamarin.Forms Page sur une Xamarin.Forms Page par la méthode
DisplayAlert . Nous pouvons fournir un titre, un corps (texte à alerter) et un / deux boutons
d'action. Page offre deux substitutions de la méthode DisplayAlert .
Cette substitution présente une boîte de dialogue d'alerte à l'utilisateur de l'application avec un
seul bouton d'annulation. L'alerte s'affiche de manière modale et une fois renvoyée, l'utilisateur
continue d'interagir avec l'application.
Exemple :
L'extrait ci-dessus présentera une implémentation native des alertes dans chaque plate-forme (
AlertDialog dans Android, UIAlertView dans iOS, MessageDialog dans Windows) comme ci-dessous.
Cette substitution présente une boîte de dialogue d'alerte à l'utilisateur de l'application avec un
bouton d'acceptation et un bouton d'annulation. Il capture la réponse d'un utilisateur en présentant
https://riptutorial.com/fr/home 18
deux boutons et en retournant un boolean . Pour obtenir une réponse d'une alerte, fournissez le
texte pour les deux boutons et attendez la méthode. Une fois que l'utilisateur a sélectionné l'une
des options, la réponse sera renvoyée au code.
Exemple :
var answer = await DisplayAlert ("Question?", "Would you like to play a game", "Yes", "No");
Debug.WriteLine ("Answer: " + (answer?"Yes":"No"));
https://riptutorial.com/fr/home 19
Chapitre 5: AppSettings Reader dans
Xamarin.Forms
Examples
Lecture du fichier app.config dans un projet Xamarin.Forms Xaml
Bien que chaque plate-forme mobile offre ses propres api de gestion des paramètres, il n'existe
aucune méthode intégrée pour lire les paramètres à partir d'un bon fichier app.config xml de style
.net; Cela est dû à un bon nombre de bonnes raisons, notamment l’api de gestion de la
configuration du framework .net, qui est plutôt lourde, et chaque plate-forme ayant son propre API
de système de fichiers.
Nous avons donc construit une bibliothèque PCLAppConfig simple, joliment empaquetée pour
votre consommation immédiate.
Cet exemple suppose que vous développez un projet Xamarin.Forms Xaml, où vous devez
accéder aux paramètres de votre modèle de vue partagé.
iOS (AppDelegate.cs)
global::Xamarin.Forms.Forms.Init();
ConfigurationManager.Initialise(PCLAppConfig.FileSystemStream.PortableStream.Current);
LoadApplication(new App());
Android (MainActivity.cs)
global::Xamarin.Forms.Forms.Init(this, bundle);
ConfigurationManager.Initialise(PCLAppConfig.FileSystemStream.PortableStream.Current);
LoadApplication(new App());
Xamarin.Forms.Forms.Init(e);
ConfigurationManager.Initialise(PCLAppConfig.FileSystemStream.PortableStream.Current);
2. Ajoutez un fichier app.config à votre projet PCL partagé et ajoutez vos entrées appSettings,
comme vous le feriez avec n'importe quel fichier app.config
<configuration>
<appSettings>
https://riptutorial.com/fr/home 20
<add key="config.text" value="hello from app.settings!" />
</appSettings>
</configuration>
3. Ajoutez ce fichier app.config PCL en tant que fichier lié sur tous vos projets de plate-forme.
Pour Android, assurez-vous de définir l'action de génération sur 'AndroidAsset' , car UWP
définit l'action de génération sur 'Contenu'
https://riptutorial.com/fr/home 21
Chapitre 6: Base de données SQL et API dans
les formulaires Xamarin.
Remarques
Créez votre propre API avec la base de données Microsoft SQL et implémentez-les dans
l'application de formulaires Xamarin.
Examples
Créer une API à l'aide d'une base de données SQL et implémenter des
formulaires Xamarin,
Lire Base de données SQL et API dans les formulaires Xamarin. en ligne:
https://riptutorial.com/fr/xamarin-forms/topic/6513/base-de-donnees-sql-et-api-dans-les-
formulaires-xamarin-
https://riptutorial.com/fr/home 22
Chapitre 7: CarouselView - Version
préliminaire
Remarques
CarouselView est un contrôle Xamarin qui peut contenir tout type de vue. Ce contrôle préalable à
la publication ne peut être utilisé que dans les projets Xamarin Forms.
Dans l'exemple fourni par James Montemagno , sur le blog de Xamarin, CarouselView est utilisé
pour afficher des images.
CarouselView n'est actuellement pas intégré à Xamarin.Forms. Pour utiliser ceci dans vos projets,
vous devrez ajouter le NuGet-Package (voir exemple ci-dessus).
Examples
Importer CarouselView
https://riptutorial.com/fr/home 23
https://riptutorial.com/fr/home 24
https://riptutorial.com/fr/xamarin-forms/topic/6094/carouselview---version-preliminaire
https://riptutorial.com/fr/home 25
Chapitre 8: Cellules Xamarin.Forms
Examples
EntryCell
Un EntryCell est une cellule qui combine les capacités d'une étiquette et d'une entrée. EntryCell
peut être utile dans des scénarios lors de la création de fonctionnalités au sein de votre
application pour collecter des données auprès de l'utilisateur. Ils peuvent facilement être placés
dans un tableau et être traités comme un simple formulaire.
XAML
Code
SwitchCell
Une SwitchCell est une cellule qui combine les capacités d'une étiquette et d'un commutateur on-
off. Une SwitchCell peut être utile pour activer ou désactiver la fonctionnalité, ou même les
préférences utilisateur ou les options de configuration.
XAML
https://riptutorial.com/fr/home 26
<SwitchCell Text="Switch It Up!" />
Code
TextCell
Un objet TextCell est une cellule comportant deux zones de texte distinctes pour l'affichage des
données. Un objet TextCell est généralement utilisé à des fins d’information dans les contrôles
TableView et ListView. Les deux zones de texte sont alignées verticalement pour maximiser
l'espace dans la cellule. Ce type de cellule est également couramment utilisé pour afficher des
données hiérarchiques. Ainsi, lorsque l'utilisateur appuie sur cette cellule, il accède à une autre
page.
XAML
Code
https://riptutorial.com/fr/home 27
ImageCell
Un ImageCell est exactement ce que cela ressemble. C'est une cellule simple qui ne contient
qu'une image. Ce contrôle fonctionne de manière très similaire à un contrôle d'image normal, mais
avec beaucoup moins de cloches et de sifflets.
XAML
<ImageCell ImageSource="http://d2g29cya9iq7ip.cloudfront.net/content/imag
es/company/aboutus-video-bg.png?v=25072014072745")),
Text="This is some text"
Detail="This is some detail" />
Code
https://riptutorial.com/fr/home 28
ViewCell
Vous pouvez considérer un ViewCell comme une ardoise vierge. C'est votre toile personnelle pour
créer une cellule qui vous ressemble exactement. Vous pouvez même le composer d'instances de
plusieurs autres objets View associées aux contrôles Layout. Tu es seulement limité par ton
imagination. Et peut-être la taille de l'écran.
XAML
<ViewCell>
<ViewCell.View>
<StackLayout>
<Button Text="My Button"/>
Code
https://riptutorial.com/fr/home 29
Lire Cellules Xamarin.Forms en ligne: https://riptutorial.com/fr/xamarin-forms/topic/7370/cellules-
xamarin-forms
https://riptutorial.com/fr/home 30
Chapitre 9: Comportement spécifique à la
plate-forme
Remarques
Plateformes cibles
if(Device.OS == TargetPlatform.Android)
{
}
else if (Device.OS == TargetPlatform.iOS)
{
}
else if (Device.OS == TargetPlatform.WinPhone)
{
}
else if (Device.OS == TargetPlatform.Windows)
{
}
else if (Device.OS == TargetPlatform.Other)
{
Examples
Supprimer l'icône dans l'en-tête de navigation dans Anroid
https://riptutorial.com/fr/home 31
Utiliser une petite image transparente appelée empty.png
https://riptutorial.com/fr/home 32
label.FontSize = label.FontSize - 2;
}
https://riptutorial.com/fr/home 33
Chapitre 10: Contact Picker - Formulaires
Xamarin (Android et iOS)
Remarques
Contact Picker XF (Android et iOS)
Examples
contact_picker.cs
using System;
using Xamarin.Forms;
namespace contact_picker
{
public class App : Application
{
public App ()
{
// The root page of your application
MainPage = new MyPage();
}
MyPage.cs
using System;
using Xamarin.Forms;
namespace contact_picker
{
public class MyPage : ContentPage
https://riptutorial.com/fr/home 34
{
Button button;
public MyPage ()
{
button = new Button {
Text = "choose contact"
};
if (Device.OS == TargetPlatform.iOS) {
await Navigation.PushModalAsync (new ChooseContactPage ());
}
else if (Device.OS == TargetPlatform.Android)
{
MessagingCenter.Send (this, "android_choose_contact", "number1");
}
};
}
}
}
ChooseContactPicker.cs
using System;
using Xamarin.Forms;
namespace contact_picker
{
public class ChooseContactPage : ContentPage
{
public ChooseContactPage ()
{
}
}
}
ChooseContactActivity.cs
https://riptutorial.com/fr/home 35
using Android.App;
using Android.OS;
using Android.Content;
using Android.Database;
using Xamarin.Forms;
namespace contact_picker.Droid
{
base.OnCreate (savedInstanceState);
cursor.MoveToFirst();
string number =
cursor.GetString(cursor.GetColumnIndexOrThrow(Android.Provider.ContactsContract.CommonDataKinds.Phone.N
}
else if (resultCode == Result.Canceled)
{
Finish ();
}
}
}
}
}
https://riptutorial.com/fr/home 36
MainActivity.cs
using System;
using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Xamarin.Forms;
namespace contact_picker.Droid
{
[Activity (Label = "contact_picker.Droid", Icon = "@drawable/icon", MainLauncher = true,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity :
global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
ChooseContactRenderer.cs
using UIKit;
using AddressBookUI;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using contact_picker;
using contact_picker.iOS;
namespace contact_picker.iOS
{
public partial class ChooseContactRenderer : PageRenderer
{
ABPeoplePickerNavigationController _contactController;
https://riptutorial.com/fr/home 37
public string type_number;
_contactController.Cancelled += delegate {
Xamarin.Forms.Application.Current.MainPage.Navigation.PopModalAsync ();
this.DismissModalViewController (true); };
if (getphones == null)
{
number = "Nothing";
}
else if (getphones.Count > 1)
{
//il ya plus de 2 num de telephone
foreach(var t in getphones)
{
number = t.Value + "/" + number;
}
}
else if (getphones.Count == 1)
{
//il ya 1 num de telephone
foreach(var t in getphones)
{
number = t.Value;
}
}
Xamarin.Forms.Application.Current.MainPage.Navigation.PopModalAsync ();
https://riptutorial.com/fr/home 38
var twopage_renderer = new MyPage();
MessagingCenter.Send<MyPage, string> (twopage_renderer, "num_select", number);
this.DismissModalViewController (true);
};
}
this.DismissModalViewController (true);
}
https://riptutorial.com/fr/home 39
Chapitre 11: Création de contrôles
personnalisés
Examples
Créez un contrôle d'entrée personnalisé Xamarin Forms (aucun élément natif
requis)
Vous trouverez ci-dessous un exemple de contrôle personnalisé Xamarin Forms pur. Aucun rendu
personnalisé n'est fait pour cela, mais pourrait facilement être implémenté, en fait, dans mon
propre code, j'utilise ce même contrôle avec un moteur de rendu personnalisé pour le Label et l'
Entry .
Le contrôle personnalisé est un ContentView avec une Label , une Entry et un BoxView , qui est
maintenu en place à l'aide de 2 StackLayout . Nous définissons également plusieurs propriétés
pouvant être liées, ainsi qu'un événement TextChanged .
Les propriétés personnalisables personnalisables sont définies comme elles sont ci-dessous et les
éléments du contrôle (dans ce cas, une Label et une Entry ) sont liés aux propriétés
personnalisables. Quelques-unes des propriétés pouvant être liées doivent également
implémenter un BindingPropertyChangedDelegate afin que les éléments liés changent leurs valeurs.
#region Properties
/// <summary>
/// Attached to the <c>InputFieldContentView</c>'s <c>ExtendedEntryOnTextChanged()</c>
event, but returns the <c>sender</c> as <c>InputFieldContentView</c>.
/// </summary>
public event System.EventHandler<TextChangedEventArgs> OnContentViewTextChangedEvent; //In
OnContentViewTextChangedEvent() we return our custom InputFieldContentView control as the
sender but we could have returned the Entry itself as the sender if we wanted to do that
instead.
https://riptutorial.com/fr/home 40
}
#endregion
public InputFieldContentView() {
BackgroundColor = Color.Transparent;
HorizontalOptions = LayoutOptions.FillAndExpand;
https://riptutorial.com/fr/home 41
entry.TextChanged += OnTextChangedEvent;
Et voici une image du produit final sur iOS (l'image montre à quoi elle ressemble lors de
l'utilisation d'un moteur de rendu personnalisé pour l' Label et l' Entry utilisées pour supprimer la
bordure sur iOS et pour spécifier une police personnalisée pour les deux éléments):
https://riptutorial.com/fr/home 42
J'ai créé une étiquette personnalisée avec un wrapper autour de la propriété FormattedText :
public MultiComponentLabel()
{
var components = new ObservableCollection<TextComponent>();
components.CollectionChanged += OnComponentsChanged;
Components = components;
}
FormattedText = formattedString;
}
}
Et lorsque la collection de composants de texte change ou que la propriété Text d'un composant
distinct change, je reconstruit la propriété FormattedText de l' Label de base.
https://riptutorial.com/fr/home 43
Et comment je l'ai utilisé dans XAML :
<ContentPage x:Name="Page"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:SuperForms.Controls;assembly=SuperForms.Controls"
x:Class="SuperForms.Samples.MultiComponentLabelPage">
<controls:MultiComponentLabel Margin="0,20,0,0">
<controls:MultiComponentLabel.Components>
<controls:TextComponent Text="Time"/>
<controls:TextComponent Text=": "/>
<controls:TextComponent Text="{Binding CurrentTime, Source={x:Reference Page}}"/>
</controls:MultiComponentLabel.Components>
</controls:MultiComponentLabel>
</ContentPage>
Codebehind de la page:
public MultiComponentLabelPage()
{
InitializeComponent();
BindingContext = this;
}
Device.StartTimer(TimeSpan.FromSeconds(1), () =>
{
CurrentTime = DateTime.Now.ToString("hh : mm : ss");
return true;
});
}
}
Le contrôle Xamarin Forms Entry ne possède pas de propriété MaxLength . Pour ce faire, vous
pouvez étendre Entry comme ci-dessous, en ajoutant une propriété Bindable MaxLength . Ensuite, il
vous suffit de vous inscrire à l’événement TextChanged sur Entry et de valider la longueur du Text à
l’appel suivant:
https://riptutorial.com/fr/home 44
class CustomEntry : Entry
{
public CustomEntry()
{
base.TextChanged += Validate;
}
if (string.IsNullOrEmpty(val))
return;
e.Text = val;
}
}
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:customControls="clr-namespace:CustomControls;assembly=CustomControls"
x:Class="Views.TestView">
<ContentView.Content>
<customControls:CustomEntry MaxLength="10" />
</ContentView.Content>
https://riptutorial.com/fr/home 45
Chapitre 12: Création de contrôles
personnalisés
Introduction
Chaque vue Xamarin.Forms est accompagnée d'un rendu pour chaque plate-forme qui crée une
instance d'un contrôle natif. Lorsqu'une vue est rendue sur la plate-forme spécifique, la classe
ViewRenderer est instanciée.
Examples
Implémenter un contrôle CheckBox
Dans cet exemple, nous allons implémenter une case à cocher personnalisée pour Android et
iOS.
namespace CheckBoxCustomRendererExample
{
public class Checkbox : View
{
public static readonly BindableProperty IsCheckedProperty =
BindableProperty.Create<Checkbox, bool>(p => p.IsChecked, true, propertyChanged: (s, o, n) =>
{ (s as Checkbox).OnChecked(new EventArgs()); });
public static readonly BindableProperty ColorProperty =
BindableProperty.Create<Checkbox, Color>(p => p.Color, Color.Default);
https://riptutorial.com/fr/home 46
{
get
{
return (Color)GetValue(ColorProperty);
}
set
{
SetValue(ColorProperty, value);
}
}
Nous commencerons par le moteur de rendu personnalisé Android en créant une nouvelle classe
( CheckboxCustomRenderer ) dans la partie Android de notre solution.
• Nous devons marquer le haut de notre classe avec l'attribut ExportRenderer pour que le
rendu soit enregistré avec Xamarin.Forms . De cette façon, Xamarin.Forms utilisera ce moteur
de rendu lorsqu'il Xamarin.Forms de créer notre objet Checkbox sur Android .
• Nous faisons la plupart de notre travail dans la méthode OnElementChanged , où nous
instancions et configurons notre contrôle natif.
https://riptutorial.com/fr/home 47
2. Remplacez la méthode OnElementChanged qui OnElementChanged le contrôle personnalisé et écrit
la logique pour le personnaliser. Cette méthode est appelée lorsque le contrôle Xamarin.Forms
correspondant est créé.
3. Ajoutez un attribut ExportRenderer à la classe de rendu personnalisée pour indiquer qu'elle
sera utilisée pour effectuer le rendu du contrôle personnalisé Xamarin.Forms . Cet attribut est
utilisé pour enregistrer le moteur de rendu personnalisé avec Xamarin.Forms .
}
}
https://riptutorial.com/fr/home 48
if (checkBox != null)
{
base.OnElementPropertyChanged(sender, e);
CheckboxPropertyChanged((Checkbox)sender, e.PropertyName);
}
}
La vue CheckBox:
namespace CheckBoxCustomRendererExample.iOS
{
[Register("CheckBoxView")]
public class CheckBoxView : UIButton
{
public CheckBoxView()
{
Initialize();
}
https://riptutorial.com/fr/home 49
public string UncheckedTitle
{
set
{
SetTitle(value, UIControlState.Normal);
}
}
void Initialize()
{
ApplyStyle();
void ApplyStyle()
{
SetImage(UIImage.FromBundle("Images/checked_checkbox.png"),
UIControlState.Selected);
SetImage(UIImage.FromBundle("Images/unchecked_checkbox.png"),
UIControlState.Normal);
}
}
}
/// <summary>
/// Handles the Element Changed event
/// </summary>
/// <param name="e">The e.</param>
protected override void OnElementChanged(ElementChangedEventArgs<Checkbox> e)
{
base.OnElementChanged(e);
if (Element == null)
return;
BackgroundColor = Element.BackgroundColor.ToUIColor();
if (e.NewElement != null)
{
if (Control == null)
{
var checkBox = new CheckBoxView(Bounds);
checkBox.TouchUpInside += (s, args) => Element.IsChecked =
https://riptutorial.com/fr/home 50
Control.Checked;
SetNativeControl(checkBox);
}
Control.Checked = e.NewElement.IsChecked;
}
Control.Frame = Frame;
Control.Bounds = Bounds;
/// <summary>
/// Handles the <see cref="E:ElementPropertyChanged" /> event.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="PropertyChangedEventArgs"/> instance containing the
event data.</param>
protected override void OnElementPropertyChanged(object sender,
PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName.Equals("Checked"))
{
Control.Checked = Element.IsChecked;
}
}
}
}
Résultat:
https://riptutorial.com/fr/home 51
https://riptutorial.com/fr/home 52
Lire Création de contrôles personnalisés en ligne: https://riptutorial.com/fr/xamarin-
forms/topic/5975/creation-de-controles-personnalises
https://riptutorial.com/fr/home 53
Chapitre 13: Création de contrôles
personnalisés
Examples
Création d'un bouton personnalisé
/// <summary>
/// Button with some additional options
/// </summary>
public class TurboButton : Button
{
public static readonly BindableProperty StringDataProperty = BindableProperty.Create(
propertyName: "StringData",
returnType: typeof(string),
declaringType: typeof(ButtonWithStorage),
defaultValue: default(string));
/// <summary>
/// You can put here some string data
/// </summary>
public string StringData
{
get { return (string)GetValue(StringDataProperty); }
set { SetValue(StringDataProperty, value); }
}
/// <summary>
/// You can put here some int data
/// </summary>
public int IntData
{
get { return (int)GetValue(IntDataProperty); }
set { SetValue(IntDataProperty, value); }
}
public TurboButton()
{
PropertyChanged += CheckIfPropertyLoaded;
}
/// <summary>
/// Called when one of properties is changed
/// </summary>
private void CheckIfPropertyLoaded(object sender, PropertyChangedEventArgs e)
{
//example of using PropertyChanged
if(e.PropertyName == "IntData")
{
https://riptutorial.com/fr/home 54
//IntData is now changed, you can operate on updated value
}
}
}
exampleControl.IntData
Notez que vous devez spécifier vous-même où votre classe TurboButton est placée dans votre
projet. Je l'ai fait dans cette ligne:
xmlns:customControls="clr-namespace:SomeApp.CustomControls;assembly=SomeApp"
Vous pouvez librement modifier "customControls" sous un autre nom. C'est à vous de voir
comment vous allez l'appeler.
https://riptutorial.com/fr/home 55
Chapitre 14: Cycle de vie de l'application
Xamarin.Forms générique? Plate-forme
dépendante!
Examples
Le cycle de vie de Xamarin.Forms n'est pas le cycle de vie réel d'une
application, mais une représentation multiplateforme de celui-ci.
Jetons un coup d’œil aux méthodes de cycle de vie des applications natives pour différentes
plates-formes.
Android.
iOS
Les fenêtres.
https://riptutorial.com/fr/home 56
//Windows.UI.Xaml.Window lifecycle methods:
public event WindowActivatedEventHandler Activated;
public event WindowClosedEventHandler Closed;
public event WindowVisibilityChangedEventHandler VisibilityChanged;
Ce que vous pouvez facilement constater en observant simplement les listes, la perspective du
cycle de vie des applications multiplates-formes de Xamarin.Forms est grandement simplifiée. Il
vous donne une idée générique sur l'état de votre application, mais dans la plupart des cas, vous
devrez créer une logique dépendant de la plate-forme.
https://riptutorial.com/fr/home 57
Chapitre 15: Déclencheurs et comportements
Examples
Exemple de déclencheur de formulaires Xamarin
Trigger sont un moyen simple d'ajouter une certaine réactivité à votre application. Un moyen facile
de le faire est d'ajouter un Trigger qui modifie une Label de TextColor selon que son connexe Entry
est le texte entré dans ou non.
L'utilisation d'un Trigger pour cela permet à Label.TextColor de passer du gris (quand aucun texte
n'est entré) au noir (dès que l'utilisateur entre du texte):
Convertisseur (chaque convertisseur reçoit une variable d' Instance utilisée dans la liaison pour
qu'une nouvelle instance de la classe ne soit pas créée à chaque utilisation):
/// <summary>
/// Used in a XAML trigger to return <c>true</c> or <c>false</c> based on the length of
<c>value</c>.
/// </summary>
public class LengthTriggerConverter : Xamarin.Forms.IValueConverter {
/// <summary>
/// Used so that a new instance is not created every time this converter is used in the
XAML code.
/// </summary>
public static LengthTriggerConverter Instance = new LengthTriggerConverter();
/// <summary>
/// If a `ConverterParameter` is passed in, a check to see if <c>value</c> is greater than
<c>parameter</c> is made. Otherwise, a check to see if <c>value</c> is over 0 is made.
/// </summary>
/// <param name="value">The length of the text from an Entry/Label/etc.</param>
/// <param name="targetType">The Type of object/control that the text/value is coming
from.</param>
/// <param name="parameter">Optional, specify what length to test against (example: for 3
Letter Name, we would choose 2, since the 3 Letter Name Entry needs to be over 2 characters),
if not specified, defaults to 0.</param>
/// <param name="culture">The current culture set in the device.</param>
/// <returns><c>object</c>, which is a <c>bool</c> (<c>true</c> if <c>value</c> is greater
than 0 (or is greater than the parameter), <c>false</c> if not).</returns>
public object Convert(object value, System.Type targetType, object parameter, CultureInfo
culture) { return DoWork(value, parameter); }
public object ConvertBack(object value, System.Type targetType, object parameter,
CultureInfo culture) { return DoWork(value, parameter); }
if(parameter != null) { //If param was specified, convert and use it, otherwise, 0 is
used
https://riptutorial.com/fr/home 58
if(!string.IsNullOrEmpty(parameterString)) { int.TryParse(parameterString, out
parameterInt); }
}
XAML (le code XAML utilise le nom x:Name de l' Entry à comprendre dans la propriété Entry.Text
est long de plus de 3 caractères):
<StackLayout>
<Label Text="3 Letter Name">
<Label.Triggers>
<DataTrigger TargetType="Label"
Binding="{Binding Source={x:Reference NameEntry},
Path=Text.Length,
Converter={x:Static
helpers:LengthTriggerConverter.Instance},
ConverterParameter=2}"
Value="False">
<Setter Property="TextColor"
Value="Gray"/>
</DataTrigger>
</Label.Triggers>
</Label>
<Entry x:Name="NameEntry"
Text="{Binding MealAmount}"
HorizontalOptions="StartAndExpand"/>
</StackLayout>
Multi déclencheurs
MultiTrigger n'est pas nécessaire fréquemment mais il y a certaines situations où il est très
pratique. MultiTrigger se comporte de la même manière que Trigger ou DataTrigger, mais il a
plusieurs conditions. Toutes les conditions doivent être remplies pour qu'un Setters tire. Voici un
exemple simple:
<!-- Text field needs to be initialized in order for the trigger to work at start -->
<Entry x:Name="email" Placeholder="Email" Text="" />
<Entry x:Name="phone" Placeholder="Phone" Text="" />
<Button Text="Submit">
<Button.Triggers>
<MultiTrigger TargetType="Button">
<MultiTrigger.Conditions>
<BindingCondition Binding="{Binding Source={x:Reference email},
Path=Text.Length}" Value="0" />
<BindingCondition Binding="{Binding Source={x:Reference phone},
Path=Text.Length}" Value="0" />
</MultiTrigger.Conditions>
<Setter Property="IsEnabled" Value="False" />
</MultiTrigger>
</Button.Triggers>
</Button>
L'exemple a deux entrées différentes, téléphone et email, et l'une d'entre elles doit être remplie.
https://riptutorial.com/fr/home 59
Le MultiTrigger désactive le bouton de soumission lorsque les deux champs sont vides.
https://riptutorial.com/fr/home 60
Chapitre 16: DependencyService
Remarques
Lorsque vous utilisez DependencyService vous avez généralement besoin de trois parties:
Lorsque vous utilisez DependencyService vous devez fournir une implémentation pour chaque plate-
forme que vous ciblez. Lorsqu'une implémentation n'est pas fournie, l'application échouera au
moment de l'exécution.
Examples
Interface
L'interface définit le comportement que vous souhaitez exposer via le service DependencyService .
Un exemple d'utilisation d'un DependencyService est un service Text-To-Speech. Il n'y a
actuellement aucune abstraction pour cette fonctionnalité dans Xamarin.Forms, vous devez donc
créer les vôtres. Commencez par définir une interface pour le comportement:
Parce que nous définissons notre interface, nous pouvons le coder à partir de notre code partagé.
Remarque: Les classes qui implémentent l'interface doivent disposer d'un constructeur sans
paramètre pour fonctionner avec DependencyService .
L'interface que vous avez définie doit être implémentée dans chaque plate-forme ciblée. Pour iOS,
cela se fait via le framework AVFoundation . L'implémentation suivante de l'interface ITextToSpeech
gère la ITextToSpeech charge d'un texte donné en anglais.
using AVFoundation;
https://riptutorial.com/fr/home 61
public void Speak (string whatToSay)
{
var speechSynthesizer = new AVSpeechSynthesizer ();
speechSynthesizer.SpeakUtterance (speechUtterance);
}
}
Lorsque vous avez créé votre classe, vous devez activer DependencyService pour le découvrir au
moment de l'exécution. Cela se fait en ajoutant un attribut [assembly] au-dessus de la définition de
classe et en dehors de toute définition d'espace de noms.
using AVFoundation;
using DependencyServiceSample.iOS;
Cet attribut enregistre la classe avec DependencyService afin de pouvoir l'utiliser lorsqu'une instance
de l'interface ITextToSpeech est requise.
Code partagé
Une fois que vous avez créé et enregistré vos classes spécifiques à la plate-forme, vous pouvez
les connecter à votre code partagé. La page suivante contient un bouton qui déclenche la
fonctionnalité de synthèse vocale à l'aide d'une phrase prédéfinie. Il utilise DependencyService pour
récupérer une implémentation spécifique à la plate-forme de ITextToSpeech au moment de
l'exécution en utilisant les SDK natifs.
public MainPage ()
{
var speakButton = new Button {
Text = "Talk to me baby!",
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
};
Content = speakButton;
}
https://riptutorial.com/fr/home 62
Lorsque vous exécutez cette application sur un appareil iOS ou Android et que vous appuyez sur
le bouton, vous entendrez l'application parler la phrase donnée.
Implémentation Android
L'implémentation spécifique à Android est un peu plus complexe car elle vous oblige à hériter d'un
Java.Lang.Object natif et vous oblige à implémenter l'interface IOnInitListener . Android exige que
vous fournissiez un contexte Android valide pour un grand nombre des méthodes SDK qu’il
expose. Xamarin.Forms expose un objet Forms.Context qui vous fournit un contexte Android que
vous pouvez utiliser dans de tels cas.
using Android.Speech.Tts;
using Xamarin.Forms;
using System.Collections.Generic;
using DependencyServiceSample.Droid;
public TextToSpeechAndroid () {}
if (_speaker == null)
{
_speaker = new TextToSpeech (ctx, this);
}
else
{
var p = new Dictionary<string,string> ();
_speaker.Speak (whatToSay, QueueMode.Flush, p);
}
}
#endregion
}
Lorsque vous avez créé votre classe, vous devez activer DependencyService pour le découvrir au
moment de l'exécution. Cela se fait en ajoutant un attribut [assembly] au-dessus de la définition de
classe et en dehors de toute définition d'espace de noms.
https://riptutorial.com/fr/home 63
using Android.Speech.Tts;
using Xamarin.Forms;
using System.Collections.Generic;
using DependencyServiceSample.Droid;
Cet attribut enregistre la classe avec DependencyService afin de pouvoir l'utiliser lorsqu'une instance
de l'interface ITextToSpeech est requise.
https://riptutorial.com/fr/home 64
Chapitre 17: Effets
Introduction
Effects simplifie les personnalisations spécifiques à la plateforme. Lorsqu'il est nécessaire de
modifier les propriétés d'un Xamarin Forms Control, vous pouvez utiliser Effects. Lorsqu'il est
nécessaire de remplacer les méthodes de Xamarin Forms Control, des moteurs de rendu
personnalisés peuvent être utilisés
Examples
Ajout d'un effet spécifique à la plate-forme pour un contrôle d'entrée
1. Créez une nouvelle application Xamarin Forms à l'aide de PCL File -> New Solution ->
Multiplatform App -> Xamarin Forms -> Forms App; Nommez le projet comme EffectsDemo
2. Sous le projet iOS, ajoutez une nouvelle classe Effect qui hérite de la classe PlatformEffect
et remplace les méthodes OnAttached , OnDetached et OnElementPropertyChanged Notez les deux
attributs ResolutionGroupName et ExportEffect , nécessaires pour ExportEffect cet effet du
projet PCL / shared.
using System;
using EffectsDemo.iOS;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ResolutionGroupName("xhackers")]
[assembly: ExportEffect(typeof(FocusEffect), "FocusEffect")]
namespace EffectsDemo.iOS
{
public class FocusEffect : PlatformEffect
{
public FocusEffect()
{
}
UIColor backgroundColor;
protected override void OnAttached()
{
try
{
Control.BackgroundColor = backgroundColor = UIColor.Red;
https://riptutorial.com/fr/home 65
}
catch (Exception ex)
{
Console.WriteLine("Cannot set attacked property" + ex.Message);
}
}
try
{
if (args.PropertyName == "IsFocused")
{
if (Control.BackgroundColor == backgroundColor)
{
Control.BackgroundColor = UIColor.Blue;
}
else
{
Control.BackgroundColor = backgroundColor;
}
}
}
catch (Exception ex)
{
Console.WriteLine("Cannot set property " + ex.Message);
}
}
}}
3. Pour consommer cet effet dans l'application, sous le projet PCL , créez une nouvelle classe
nommée FocusEffect qui hérite de RoutingEffect . Ceci est essentiel pour que le PCL
instancie la mise en œuvre spécifique de la plate-forme de l'effet. Exemple de code ci-
dessous:
using Xamarin.Forms;
namespace EffectsDemo
{
public class FocusEffect : RoutingEffect
{
public FocusEffect() : base("xhackers.FocusEffect")
{
}
}
}
https://riptutorial.com/fr/home 66
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-
namespace:EffectsDemo" x:Class="EffectsDemo.EffectsDemoPage">
<StackLayout Orientation="Horizontal" HorizontalOptions="Center"
VerticalOptions="Center">
<Label Text="Effects Demo" HorizontalOptions="StartAndExpand" VerticalOptions="Center"
></Label>
<Entry Text="Controlled by effects" HorizontalOptions="FillAndExpand"
VerticalOptions="Center">
<Entry.Effects>
<local:FocusEffect>
</local:FocusEffect>
</Entry.Effects>
</Entry>
</StackLayout>
</ContentPage>
https://riptutorial.com/fr/home 67
https://riptutorial.com/fr/home 68
Étant donné que l'effet a été implémenté uniquement dans la version iOS, lorsque l'application
s'exécute dans iOS Simulator en concentrant les changements de couleur d'arrière-plan Entry et
que rien ne se produit dans Android Emulator car l' Effect n'a pas été créé dans le projet Droid
https://riptutorial.com/fr/home 69
Chapitre 18: Geste Xamarin
Examples
Touchez le geste
Avec le geste tap, vous pouvez faire en sorte que tout élément de l'interface utilisateur soit
cliquable (images, boutons, StackLayouts, ...):
<Image Source="tapped.jpg">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="OnTapGestureRecognizerTapped" Command="{Binding
TapCommand"} />
</Image.GestureRecognizers>
</Image>
https://riptutorial.com/fr/home 70
Chapitre 19: Geste Xamarin
Examples
Événement gestuel
Lorsque nous mettons le contrôle de Label, le Label ne fournit aucun événement. <Label x: Name
= "lblSignUp Text =" Vous n'avez pas de compte? "/> Comme indiqué dans le but d'affichage
uniquement Label.
Lorsque l'utilisateur souhaite remplacer Button par une étiquette, nous donnons l'événement pour
Label. Comme indiqué ci-dessous:
XAML
C#
L'écran ci-dessous montre l'événement Label. Écran 1: L'étiquette "Vous n'avez pas de compte?"
comme indiqué en bas.
https://riptutorial.com/fr/home 71
https://riptutorial.com/fr/home 72
Chapitre 20: Gestes
Examples
Faire une image tappable en ajoutant un TapGestureRecognizer
Il existe deux types de reconnaissance par défaut disponibles dans Xamarin.Forms, l’un d’entre
eux est le TapGestureRecognizer .
Vous pouvez les ajouter à pratiquement n'importe quel élément visuel. Jetez un oeil à une
implémentation simple qui se lie à une Image . Voici comment le faire en code.
Ou en XAML:
<Image Source="tapped.jpg">
<Image.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding TappedCommand}"
NumberOfTapsRequired="2" />
</Image.GestureRecognizers>
</Image>
Ici, la commande est définie à l'aide de la liaison de données. Comme vous pouvez le voir, vous
pouvez également définir le NumberOfTapsRequired pour l'activer pour plus de taps avant d'agir. La
valeur par défaut est 1 tapotement.
Afin de rendre une Image (ou tout autre élément visuel) zoomable, nous devons lui ajouter un
PinchGestureRecognizer . Voici comment le faire en code:
image.GestureRecognizers.Add(pinchGesture);
https://riptutorial.com/fr/home 73
<Image Source="waterfront.jpg">
<Image.GestureRecognizers>
<PinchGestureRecognizer PinchUpdated="OnPinchUpdated" />
</Image.GestureRecognizers>
</Image>
Dans le gestionnaire d'événement accompagné, vous devez fournir le code pour zoomer sur votre
image. Bien entendu, d'autres utilisations peuvent également être mises en œuvre.
Lorsque vous avez une Image agrandie (ou un autre contenu), vous pouvez faire glisser l' Image
pour afficher tout son contenu dans l'état agrandi.
Cela peut être réalisé en implémentant le PanGestureRecognizer. Du code cela ressemble à ça:
image.GestureRecognizers.Add(panGesture);
<Image Source="MonoMonkey.jpg">
<Image.GestureRecognizers>
<PanGestureRecognizer PanUpdated="OnPanUpdated" />
</Image.GestureRecognizers>
</Image>
Les détecteurs de gestes intégrés Xamarins ne fournissent qu'une manipulation tactile très simple.
Par exemple, il n'y a aucun moyen d'obtenir la position d'un doigt touchant. MR.Gestures est un
https://riptutorial.com/fr/home 74
composant qui ajoute 14 événements de traitement tactile différents. La position des doigts qui se
touchent fait partie de EventArgs transmis à tous les événements MR.Gestures.
Si vous souhaitez placer une épingle n'importe où sur l'écran, le plus simple est d'utiliser un
MR.Gestures.AbsoluteLayout qui gère l'événement Tapping .
Comme vous pouvez le voir, Tapping="OnTapping" ressemble plus à la syntaxe .NET que Xamarins
avec les GestureRecognizers imbriqués. Cette syntaxe a été copiée depuis iOS et ça sent un peu
pour les développeurs .NET.
Dans votre code, vous pouvez ajouter le gestionnaire OnTapping comme OnTapping :
Vous trouverez d'autres exemples pour MR.Gestures dans l' application GestureSample sur
GitHub et sur le site Web de MR.Gestures . Ils montrent également comment utiliser tous les
autres événements tactiles avec les gestionnaires d'événements, les commandes, MVVM, ...
https://riptutorial.com/fr/home 75
Chapitre 21: Gestion des exceptions
Examples
Une façon de signaler les exceptions sur iOS
Accédez au fichier Main.cs dans le projet iOS et modifiez le code existant, comme présenté ci-
dessous:
ILittleWatson interface ILittleWatson , utilisée dans le code portable, pourrait ressembler à ceci:
[assembly: Xamarin.Forms.Dependency(typeof(LittleWatson))]
namespace SomeNamespace
{
public class LittleWatson : ILittleWatson
{
private const string FileName = "Report.txt";
static LittleWatson()
{
DocumentsFolder =
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
FilePath = Path.Combine(DocumentsFolder, FileName);
}
https://riptutorial.com/fr/home 76
public async Task<bool> SendReport()
{
_sendingTask = new TaskCompletionSource<bool>();
try
{
var text = File.ReadAllText(FilePath);
File.Delete(FilePath);
if (MFMailComposeViewController.CanSendMail)
{
var email = ""; // Put receiver email here.
var mailController = new MFMailComposeViewController();
mailController.SetToRecipients(new string[] { email });
mailController.SetSubject("iPhone error");
mailController.SetMessageBody(text, false);
mailController.Finished += (object s, MFComposeResultEventArgs args) =>
{
args.Controller.DismissViewController(true, null);
_sendingTask.TrySetResult(true);
};
ShowViewController(mailController);
}
}
catch (FileNotFoundException)
{
// No errors found.
_sendingTask.TrySetResult(false);
}
https://riptutorial.com/fr/home 77
Lire Gestion des exceptions en ligne: https://riptutorial.com/fr/xamarin-forms/topic/6428/gestion-
des-exceptions
https://riptutorial.com/fr/home 78
Chapitre 22: Liaison de données
Remarques
Exceptions possibles
System.ArrayTypeMismatchException: Vous avez tenté
d'accéder à un élément en tant que type incompatible avec le
tableau.
Cette exception peut se produire lors de la tentative de liaison d'une collection à une propriété
non-liée lorsque la pré-compilation XAML est activée. Un exemple courant est la tentative de
liaison à Picker.Items . Voir ci-dessous.
ou
Plus précisément, la propriété Items est non-bindable. Les solutions incluent la création de votre
propre contrôle personnalisé ou l'utilisation d'un contrôle tiers, tel que BindablePicker partir de
https://riptutorial.com/fr/home 79
FreshEssentials . Après avoir installé le package FreshEssentials NuGet dans votre projet, le
contrôle BindablePicker du BindablePicker avec une propriété ItemsSource pouvant être ItemsSource
est disponible:
Examples
Liaison de base à ViewModel
EntryPage.xaml:
MyViewModel.cs:
using System;
using System.ComponentModel;
namespace MyAssembly.ViewModel
{
public class MyViewModel : INotifyPropertyChanged
{
https://riptutorial.com/fr/home 80
private string _name = String.Empty;
private string _phone = String.Empty;
public MyViewModel()
{
SaveCommand = new Command(SaveCommandExecute);
}
https://riptutorial.com/fr/home 81
Chapitre 23: MessagingCenter
Introduction
Xamarin.Forms dispose d'un mécanisme de messagerie intégré pour promouvoir le code
découplé. De cette façon, les modèles de vue et les autres composants n'ont pas besoin de se
connaître. Ils peuvent communiquer via un simple contrat de messagerie.
S'abonner écoutez les messages avec une certaine signature (le contrat) et exécutez le code
lorsqu'un message est reçu. Un message peut avoir plusieurs abonnés.
Examples
Exemple simple
public FooMessaging()
{
MessagingCenter.Subscribe<MainPage> (this, "Hi", (sender) => {
this.Greeting = "Hi there!";
});
}
}
Pour envoyer un message déclenchant cette fonctionnalité, nous devons avoir une page appelée
MainPage et implémenter le code comme ci-dessous.
https://riptutorial.com/fr/home 82
Dans notre MainPage nous avons un bouton avec un gestionnaire qui envoie un message. this
devrait être une instance de MainPage .
Arguments de passage
Vous pouvez également transmettre des arguments avec un message avec lequel travailler.
Nous utiliserons les classifiés de notre exemple précédent et les étendrons. Dans la partie
réceptrice, juste derrière l'appel de la méthode Subscribe , ajoutez le type d'argument attendu.
Assurez-vous également de déclarer également les arguments dans la signature du gestionnaire.
public FooMessaging()
{
MessagingCenter.Subscribe<MainPage, string> (this, "Hi", (sender, arg) => {
this.Greeting = arg;
});
}
}
Lors de l'envoi d'un message, veillez à inclure la valeur de l'argument. En outre, vous ajoutez ici le
type juste derrière la méthode Send et ajoutez la valeur de l'argument.
Dans cet exemple, une chaîne simple est utilisée, mais vous pouvez également utiliser tout autre
type d'objets (complexes).
Se désabonner
Lorsque vous n'avez plus besoin de recevoir de messages, vous pouvez simplement vous
désabonner. Vous pouvez le faire comme ceci:
Lorsque vous fournissez des arguments, vous devez vous désabonner de la signature complète,
comme ceci:
https://riptutorial.com/fr/home 83
Chapitre 24: Mise en cache
Examples
Mise en cache avec Akavache
A propos d'Akavache
Akavache est une bibliothèque incroyablement utile fournissant des fonctionnalités de mise en
cache pour la mise en cache de vos données. Akavache fournit une interface de stockage de
valeur clé et travaille sur le dessus de SQLite3. Vous n'avez pas besoin de garder votre schéma
synchronisé car il ne s'agit en fait que de la solution No-SQL, ce qui le rend parfait pour la plupart
des applications mobiles, en particulier si votre application doit être mise à jour souvent sans perte
de données.
• Vous avez besoin de votre application pour mettre en cache les données pendant une
période donnée (vous pouvez configurer le délai d'expiration pour chaque entité enregistrée;
• Vous voulez que votre application fonctionne hors connexion;
• Il est difficile de déterminer et de geler le schéma de vos données. Par exemple, vous avez
des listes contenant différents objets typés;
• Il suffit que vous ayez un accès simple à la valeur-clé aux données et que vous n'ayez pas
besoin de faire des requêtes complexes.
Akavache n'est pas une "solution miracle" pour le stockage des données, alors réfléchissez bien à
son utilisation dans les cas suivants:
En fait, vous pouvez migrer manuellement vos données simplement en les lisant et en
les écrivant avec des champs mis à jour.
https://riptutorial.com/fr/home 84
Exemple simple
L'interaction avec Akavache se fait principalement via un objet appelé BlobCache .
La plupart des méthodes d'Akavache renvoient des observables réactifs, mais vous pouvez aussi
les attendre grâce aux méthodes d'extension.
// Make sure you set the application name before doing any inserts or gets
BlobCache.ApplicationName = "AkavacheExperiment";
//
// ...later, in another part of town...
//
// Using async/await
var toaster = await BlobCache.UserAccount.GetObject<Toaster>("toaster");
// or without async/await
Toaster toaster;
BlobCache.UserAccount.GetObject<Toaster>("toaster")
.Subscribe(x => toaster = x, ex => Console.WriteLine("No Key!"));
try {
toaster = await BlobCache.UserAccount.GetObjectAsync("toaster");
} catch (KeyNotFoundException ex) {
toaster = new Toaster();
}
// Or without async/await:
toaster = await BlobCache.UserAccount.GetObjectAsync<Toaster>("toaster")
.Catch(Observable.Return(new Toaster()));
https://riptutorial.com/fr/home 85
Chapitre 25: Mise en forme de Xamarin
Examples
ContentPresenter
Un gestionnaire de disposition pour les vues modélisées. Utilisé dans un ControlTemplate pour
marquer l'emplacement du contenu à présenter.
ContentView
Un élément avec un seul contenu. ContentView a très peu d'utilisation. Son but est de servir de
classe de base pour les vues composées définies par l'utilisateur.
https://riptutorial.com/fr/home 86
XAML
<ContentView>
<Label Text="Hi, I'm a simple Label inside of a simple ContentView"
HorizontalOptions="Center"
VerticalOptions="Center"/>
</ContentView>
Code
Cadre
Un élément contenant un seul enfant, avec des options de cadrage. Frame ont un défaut
Xamarin.Forms.Layout.Padding de 20.
https://riptutorial.com/fr/home 87
XAML
<Frame>
<Label Text="I've been framed!"
HorizontalOptions="Center"
VerticalOptions="Center" />
</Frame>
Code
ScrollView
ScrollView contient des dispositions et leur permet de faire défiler l'écran. ScrollView est également
utilisé pour permettre aux vues de se déplacer automatiquement dans la partie visible de l'écran
https://riptutorial.com/fr/home 88
lorsque le clavier est affiché.
Remarque: les ScrollViews ne doivent pas être imbriquées. De plus, les ScrollViews ne doivent
pas être imbriquées avec d'autres contrôles fournissant un défilement, tels que ListView et WebView
.
<ContentPage.Content>
<ScrollView>
<StackLayout>
<BoxView BackgroundColor="Red" HeightRequest="600" WidthRequest="150" />
<Entry />
</StackLayout>
</ScrollView>
</ContentPage.Content>
https://riptutorial.com/fr/home 89
TemplatedView
Un élément qui affiche le contenu avec un modèle de contrôle et la classe de base pour
ContentView .
AbsoluteLayout
https://riptutorial.com/fr/home 90
Une définition d'un AbsoluteLayout dans XAML ressemble à ceci:
<AbsoluteLayout>
<Label Text="I'm centered on iPhone 4 but no other device"
AbsoluteLayout.LayoutBounds="115,150,100,100" LineBreakMode="WordWrap" />
<Label Text="I'm bottom center on every device."
AbsoluteLayout.LayoutBounds=".5,1,.5,.1" AbsoluteLayout.LayoutFlags="All"
LineBreakMode="WordWrap" />
<BoxView Color="Olive" AbsoluteLayout.LayoutBounds="1,.5, 25, 100"
AbsoluteLayout.LayoutFlags="PositionProportional" />
<BoxView Color="Red" AbsoluteLayout.LayoutBounds="0,.5,25,100"
AbsoluteLayout.LayoutFlags="PositionProportional" />
<BoxView Color="Blue" AbsoluteLayout.LayoutBounds=".5,0,100,25"
AbsoluteLayout.LayoutFlags="PositionProportional" />
<BoxView Color="Blue" AbsoluteLayout.LayoutBounds=".5,0,1,25"
AbsoluteLayout.LayoutFlags="PositionProportional, WidthProportional" />
</AbsoluteLayout>
https://riptutorial.com/fr/home 91
AbsoluteLayout.SetLayoutBounds (centerLabel, new Rectangle (115, 159, 100, 100));
// No need to set layout flags, absolute positioning is the default
var bottomLabel = new Label { Text = "I'm bottom center on every device.", LineBreakMode =
LineBreakMode.WordWrap };
AbsoluteLayout.SetLayoutBounds (bottomLabel, new Rectangle (.5, 1, .5, .1));
AbsoluteLayout.SetLayoutFlags (bottomLabel, AbsoluteLayoutFlags.All);
layout.Children.Add (bottomLabel);
layout.Children.Add (centerLabel);
layout.Children.Add (rightBox);
layout.Children.Add (leftBox);
layout.Children.Add (topBox);
Il existe différentes manières de définir les limites des éléments enfants en fonction de
l'énumération AbsoluteLayoutFlags utilisée pendant ce processus. L'énumération
AbsoluteLayoutFlags contient les valeurs suivantes:
Le processus de travail avec la mise en page du conteneur AbsoluteLayout peut sembler un peu
contre-intuitif au début, mais avec un peu d’utilisation, il deviendra familier. Une fois que vous
avez créé vos éléments enfants, pour les définir dans une position absolue dans le conteneur,
vous devez suivre trois étapes. Vous souhaiterez définir les indicateurs assignés aux éléments à
l'aide de la méthode AbsoluteLayout.SetLayoutFlags () . Vous voudrez également utiliser la
méthode AbsoluteLayout.SetLayoutBounds () pour donner aux éléments leurs limites. Enfin,
vous voudrez ajouter les éléments enfants à la collection Children. Étant donné que
https://riptutorial.com/fr/home 92
Xamarin.Forms est une couche d'abstraction entre Xamarin et les implémentations spécifiques
aux périphériques, les valeurs de position peuvent être indépendantes des pixels du périphérique.
C'est là que les indicateurs de disposition mentionnés précédemment entrent en jeu. Vous pouvez
choisir comment le processus de mise en page des contrôles Xamarin.Forms doit interpréter les
valeurs que vous définissez.
la grille
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<RowDefinition Height="*" />
<RowDefinition Height="200" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
https://riptutorial.com/fr/home 93
<ContentView Grid.Row="0" Grid.Column="1"/>
<ContentView Grid.Row="1" Grid.Column="1"/>
<ContentView Grid.Row="2" Grid.Column="1"/>
</Grid>
<Grid>
<--DEFINITIONS...--!>
</Grid>
En code C #:
https://riptutorial.com/fr/home 94
spécifiques et fixes. Spécifié comme valeur et GridUnitType.Absolute en C # et en # dans
XAML, # étant la valeur souhaitée.
Remarque: Les valeurs de largeur des colonnes sont définies par défaut sur Auto dans
Xamarin.Forms, ce qui signifie que la largeur est déterminée par la taille des enfants. Notez que
cela diffère de l'implémentation de XAML sur les plates-formes Microsoft, où la largeur par défaut
est *, ce qui remplira l'espace disponible.
Disposition relative
Une Layout qui utilise des Constraints pour mettre en forme ses enfants.
<RelativeLayout>
<BoxView Color="Red" x:Name="redBox"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent,
Property=Height,Factor=.15,Constant=0}"
https://riptutorial.com/fr/home 95
RelativeLayout.WidthConstraint="{ConstraintExpression
Type=RelativeToParent,Property=Width,Factor=1,Constant=0}"
RelativeLayout.HeightConstraint="{ConstraintExpression
Type=RelativeToParent,Property=Height,Factor=.8,Constant=0}" />
<BoxView Color="Blue"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView,
ElementName=redBox,Property=Y,Factor=1,Constant=20}"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToView,
ElementName=redBox,Property=X,Factor=1,Constant=20}"
RelativeLayout.WidthConstraint="{ConstraintExpression
Type=RelativeToParent,Property=Width,Factor=.5,Constant=0}"
RelativeLayout.HeightConstraint="{ConstraintExpression
Type=RelativeToParent,Property=Height,Factor=.5,Constant=0}" />
</RelativeLayout>
StackLayout
StackLayout organise les vues dans une ligne unidimensionnelle ("pile"), horizontalement ou
verticalement. Views dans un StackLayout peuvent être dimensionnées en fonction de l'espace dans
la mise en page à l'aide des options de présentation. Le positionnement est déterminé par les
vues de commande qui ont été ajoutées à la mise en page et aux options de disposition des vues.
https://riptutorial.com/fr/home 96
Utilisation dans XAML
<StackLayout>
<Label Text="This will be on top" />
<Button Text="This will be on the bottom" />
</StackLayout>
https://riptutorial.com/fr/home 97
HorizontalOptions = LayoutOptions.Center
},
new Label
{
Text = "vertically",
HorizontalOptions = LayoutOptions.End
},
new Label
{
Text = "by default,",
HorizontalOptions = LayoutOptions.Center
},
new Label
{
Text = "but horizontal placement",
HorizontalOptions = LayoutOptions.Start
},
new Label
{
Text = "can be controlled with",
HorizontalOptions = LayoutOptions.Center
},
new Label
{
Text = "the HorizontalOptions property.",
HorizontalOptions = LayoutOptions.End
},
new Label
{
Text = "An Expand option allows one or more children " +
"to occupy the an area within the remaining " +
"space of the StackLayout after it's been sized " +
"to the height of its parent.",
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.End
},
new StackLayout
{
Spacing = 0,
Orientation = StackOrientation.Horizontal,
Children =
{
new Label
{
Text = "Stacking",
},
new Label
{
Text = "can also be",
HorizontalOptions = LayoutOptions.CenterAndExpand
},
new Label
{
Text = "horizontal.",
},
}
}
}
};
https://riptutorial.com/fr/home 98
en-forme-de-xamarin
https://riptutorial.com/fr/home 99
Chapitre 26: Mise en page relative au Xamarin
Remarques
L'utilisation de ForceLayout dans ce cas
La taille des étiquettes et des boutons change en fonction du texte à l'intérieur d'eux. Par
conséquent, lorsque les enfants sont ajoutés à la mise en page, leur taille reste égale à 0 en
largeur et en hauteur. Par exemple:
relativeLayout.Children.Add(label,
Constraint.RelativeToParent(parent => label.Width));
L'expression ci-dessus renverra 0 car la largeur est 0 pour le moment. Pour contourner ce
problème , nous devons écouter l'événement SizeChanged et, lorsque la taille change, nous
devons forcer la mise en page afin de la redessiner.
Pour une vue comme BoxView, c'est inutile. Parce que nous pouvons définir leurs tailles lors de
l'instanciation. L'autre chose est que, dans les deux cas, nous pouvons définir leur largeur et leur
hauteur comme une contrainte lorsque nous les ajoutons à la mise en page. Par exemple:
relativeLayout.Children.Add(label,
Constraint.Constant(0),
Constraint.Constant(0),
//Width constraint
Constraint.Constant(30),
//Height constraint
Constraint.Constant(40));
Examples
Page avec une étiquette simple au milieu
https://riptutorial.com/fr/home 100
public class MyPage : ContentPage
{
RelativeLayout _layout;
Label MiddleText;
public MyPage()
{
_layout = new RelativeLayout();
_layout.Children.Add(MiddleText
Constraint.RelativeToParent(parent => parent.Width / 2 - MiddleText.Width / 2),
Constraint.RelativeToParent(parent => parent.Height / 2 - MiddleText.Height / 2));
Content = _layout;
}
}
https://riptutorial.com/fr/home 101
Boîte après boîte
BoxView centerBox;
BoxView rightBox;
BoxView leftBox;
BoxView topBox;
BoxView bottomBox;
public MyPage()
{
_layout = new RelativeLayout();
https://riptutorial.com/fr/home 102
WidthRequest = boxSize,
HeightRequest = boxSize
};
//First adding center box since other boxes will be relative to center box
_layout.Children.Add(centerBox,
//Constraint for X, centering it horizontally
//We give the expression as a paramater, parent is our layout in this case
Constraint.RelativeToParent(parent => parent.Width / 2 - boxSize / 2),
//Constraint for Y, centering it vertically
Constraint.RelativeToParent(parent => parent.Height / 2 - boxSize / 2),
//Constraint for Width
Constraint.Constant(boxSize),
//Constraint for Height
Constraint.Constant(boxSize));
_layout.Children.Add(leftBox,
//The x constraint will relate on some level to centerBox
//Which is the first parameter in this case
//We both need to have parent and centerBox, which will be called sibling,
//in our expression paramters
//This expression will be our second paramater
Constraint.RelativeToView(centerBox, (parent, sibling) => sibling.X - spacing -
boxSize),
//Since we only need to move it left,
//it's Y constraint will be centerBox' position at Y axis
Constraint.RelativeToView(centerBox, (parent, sibling) => sibling.Y)
//No need to define the size constraints
//Since we initialize them during instantiation
);
_layout.Children.Add(rightBox,
//The only difference hear is adding spacing and boxSize instead of substracting
them
Constraint.RelativeToView(centerBox, (parent, sibling) => sibling.X + spacing +
boxSize),
Constraint.RelativeToView(centerBox, (parent, sibling) => sibling.Y)
);
_layout.Children.Add(topBox,
https://riptutorial.com/fr/home 103
//Since we are going to move it vertically this thime
//We need to do the math on Y Constraint
//In this case, X constraint will be centerBox' position at X axis
Constraint.RelativeToView(centerBox, (parent, sibling) => sibling.X),
//We will do the math on Y axis this time
Constraint.RelativeToView(centerBox, (parent, sibling) => sibling.Y - spacing -
boxSize)
);
_layout.Children.Add(bottomBox,
Constraint.RelativeToView(centerBox, (parent, sibling) => sibling.X),
Constraint.RelativeToView(centerBox, (parent, sibling) => sibling.Y + spacing +
boxSize)
);
Content = _layout;
}
}
https://riptutorial.com/fr/home 104
Chapitre 27: Navigation dans Xamarin.Forms
Examples
Flux de navigation
using System;
using Xamarin.Forms;
namespace NavigationApp
{
public class App : Application
{
public App()
{
MainPage = new NavigationPage(new FirstPage());
}
}
public FirstPage()
{
Title = "First page";
Content = content;
}
public SecondPage()
{
Title = "Second page";
Content = SecondPageLabel;
https://riptutorial.com/fr/home 105
}
}
}
Fichier App.xaml.cs (le fichier App.xaml est défini par défaut, donc ignoré)
using Xamrin.Forms
namespace NavigationApp
{
public partial class App : Application
{
public static INavigation GlobalNavigation { get; private set; }
public App()
{
InitializeComponent();
var rootPage = new NavigationPage(new FirstPage());
GlobalNavigation = rootPage.Navigation;
MainPage = rootPage;
}
}
}
Fichier FirstPage.xaml
Dans certains cas, vous devez ouvrir la nouvelle page non pas dans la navigation actuelle, mais
dans la navigation globale. Par exemple, si votre page actuelle contient un menu inférieur, elle
sera visible lorsque vous poussez la nouvelle page dans la navigation actuelle. Si vous souhaitez
que la page soit ouverte sur tout le contenu visible en masquant le menu inférieur et le contenu de
la page en cours, vous devez insérer la nouvelle page en tant que modal dans la navigation
https://riptutorial.com/fr/home 106
globale. Voir la propriété App.GlobalNavigation et l'exemple ci-dessous.
Fichier FirstPage.xaml.cs
using System;
using Xamarin.Forms;
namespace NavigationApp
{
public partial class FirstPage : ContentPage
{
public FirstPage()
{
InitializeComponent();
}
Fichier SecondPage.xaml (le fichier xaml.cs est défini par défaut, donc ignoré)
Par défaut, le modèle de navigation fonctionne comme une pile de pages, appelant les pages les
plus récentes sur les pages précédentes. Vous devrez utiliser l'objet NavigationPage pour cela.
...
public class App : Application
{
public App()
{
MainPage = new NavigationPage(new Page1());
https://riptutorial.com/fr/home 107
}
}
...
Page1.xaml
...
<ContentPage.Content>
<StackLayout>
<Label Text="Page 1" />
<Button Text="Go to page 2" Clicked="GoToNextPage" />
</StackLayout>
</ContentPage.Content>
...
Page1.xaml.cs
...
public partial class Page1 : ContentPage
{
public Page1()
{
InitializeComponent();
}
Page2.xaml
...
<ContentPage.Content>
<StackLayout>
<Label Text="Page 2" />
<Button Text="Go to Page 3" Clicked="GoToNextPage" />
</StackLayout>
</ContentPage.Content>
...
Page2.xaml.cs
...
public partial class Page2 : ContentPage
{
public Page2()
{
InitializeComponent();
}
https://riptutorial.com/fr/home 108
{
await Navigation.PushAsync(new Page3());
}
}
...
Pages de découpage
Normalement, l'utilisateur utilise le bouton Précédent pour renvoyer des pages, mais il est parfois
nécessaire de le contrôler par programmation, vous devez donc appeler la méthode
NavigationPage.PopAsync () pour revenir à la page précédente ou
NavigationPage.PopToRootAsync () pour revenir au début. comme par exemple ...
Page3.xaml
...
<ContentPage.Content>
<StackLayout>
<Label Text="Page 3" />
<Button Text="Go to previous page" Clicked="GoToPreviousPage" />
<Button Text="Go to beginning" Clicked="GoToStartPage" />
</StackLayout>
</ContentPage.Content>
...
Page3.xaml.cs
...
public partial class Page3 : ContentPage
{
public Page3()
{
InitializeComponent();
}
https://riptutorial.com/fr/home 109
• Pour les feuilles d'action qui sont des menus contextuels
...
// to open
await Navigation.PushModalAsync(new ModalPage());
// to close
await Navigation.PopModalAsync();
...
...
// alert
await DisplayAlert("Alert title", "Alert text", "Ok button text");
// confirmation
var booleanAnswer = await DisplayAlert("Confirm?", "Confirmation text", "Yes", "No");
...
Feuilles d'Action
...
var selectedOption = await DisplayActionSheet("Options", "Cancel", "Destroy", "Option 1",
"Option 2", "Option 3");
...
public App ()
{
// The root page of your application
MainPage = new RootPage();
}
}
public class RootPage : MasterDetailPage
{
public RootPage()
{
var menuPage = new MenuPage();
menuPage.Menu.ItemSelected += (sender, e) => NavigateTo(e.SelectedItem as MenuItem);
Master = menuPage;
App.NavPage = new NavigationPage(new HomePage());
Detail = App.NavPage;
}
protected override async void OnAppearing()
{
base.OnAppearing();
https://riptutorial.com/fr/home 110
}
void NavigateTo(MenuItem menuItem)
{
Page displayPage = (Page)Activator.CreateInstance(menuItem.TargetType);
Detail = new NavigationPage(displayPage);
IsPresented = false;
}
}
Le code ci-dessous montre comment effectuer une navigation asynchrone lorsque l'application se
trouve dans un contexte MasterDetailPage.
await navigationPage.Navigation.PushAsync(page);
navigationPage.Navigation.RemovePage(navigationPage.Navigation.NavigationStack[navigationPage.Navigatio
- 2]);
masterDetail.IsPresented = false;
}
https://riptutorial.com/fr/home 111
Chapitre 28: Navigation dans Xamarin.Forms
Remarques
La navigation sur Xamarin.Forms repose sur deux principaux modes de navigation: hiérarchique
et modal.
Le modèle hiérarchique permet à l'utilisateur de descendre dans une pile de pages et de revenir
en appuyant sur le bouton "retour" / "haut".
Le modèle modal est une page d'interruption nécessitant une action spécifique de l'utilisateur,
mais peut normalement être annulée en appuyant sur le bouton Annuler. Quelques exemples sont
les notifications, les alertes, les boîtes de dialogue et les pages de registre / édition.
Examples
Utiliser INavigation à partir du modèle de vue
La première étape consiste à créer une interface de navigation que nous utiliserons sur le modèle
de vue:
Dans la méthode Initialize , j'utilise mon mappeur personnalisé où je conserve une collection de
types de pages avec des clés associées.
https://riptutorial.com/fr/home 112
return typeSource;
}
return associatedSource;
}
}
Fichier App.cs :
Dans mapper, j'ai associé le type d'une page à une valeur enum.
IViewNavigationService :
[assembly: Dependency(typeof(ViewNavigationService))]
namespace SuperForms.Core.ViewNavigation
{
public class ViewNavigationService : IViewNavigationService
{
private INavigation _navigation;
private SuperMapper _navigationMapper;
https://riptutorial.com/fr/home 113
{
_navigation = navigation;
_navigationMapper = navigationMapper;
}
if (type == null)
{
throw new InvalidOperationException(
"Can't find associated type for " + navigationSource.ToString());
}
ConstructorInfo constructor;
object[] parameters;
if (parameter == null)
{
constructor = type.GetTypeInfo()
.DeclaredConstructors
.FirstOrDefault(c => !c.GetParameters().Any());
if (constructor == null)
{
throw new InvalidOperationException(
"No suitable constructor found for page " + navigationSource.ToString());
}
await _navigation.PushAsync(page);
}
await _navigation.PopAsync();
}
https://riptutorial.com/fr/home 114
{
if (_navigation == null || _navigationMapper == null)
throw new NullReferenceException("Call Initialize method first.");
}
}
}
J'obtiens le type de page sur lequel l'utilisateur souhaite naviguer et créer son instance en utilisant
la réflexion.
https://riptutorial.com/fr/home 115
Chapitre 29: Notifications push
Remarques
Il n'y a pas de méthode uniforme pour gérer les notifications push dans Xamarin Forms, car
l'implémentation dépend fortement des fonctionnalités et événements spécifiques à la plateforme.
Le code spécifique à la plate-forme sera donc toujours nécessaire.
Cependant, en utilisant DependencyService vous pouvez partager autant de code que possible. Il y a
aussi un plugin conçu pour cela par rdelrosario, qui peut être trouvé sur son GitHub .
Le code et les captures d'écran sont tirés d'une série de blogs de Gerald Versluis qui explique le
processus plus en détail.
Examples
Notifications Push pour iOS avec Azure
Pour démarrer l'enregistrement des notifications push, vous devez exécuter le code ci-dessous.
UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
UIApplication.SharedApplication.RegisterForRemoteNotifications();
Ce code peut être soit directement couru lorsque l'application démarre dans le FinishedLaunching
dans le AppDelegate.cs fichier. Vous pouvez également le faire chaque fois qu'un utilisateur décide
d'activer les notifications push.
L'exécution de ce code déclenchera une alerte pour inviter l'utilisateur à accepter que l'application
puisse lui envoyer des notifications. Donc, implémentez également un scénario où l'utilisateur le
nie!
https://riptutorial.com/fr/home 116
Ce sont les événements qui nécessitent une implémentation pour implémenter les notifications
push sur iOS. Vous pouvez les trouver dans le fichier AppDelegate.cs .
// We've successfully registered with the Apple notification service, or in our case Azure
public override void RegisteredForRemoteNotifications(UIApplication application, NSData
deviceToken)
{
// Modify device token for compatibility Azure
var token = deviceToken.Description;
https://riptutorial.com/fr/home 117
token = token.Trim('<', '>').Replace(" ", "");
NSSet tags = null; // create tags if you want, not covered for now
hub.RegisterNativeAsync(deviceToken, tags, (errorCallback) =>
{
if (errorCallback != null)
{
var alert = new UIAlertView("ERROR!", errorCallback.ToString(), null, "OK", null);
alert.Show();
}
});
}
if (success)
{
var alert = new UIAlertView("Notification!", inAppMessage.ToString(), null, "OK",
null);
alert.Show();
}
}
alert.Show();
}
https://riptutorial.com/fr/home 118
Notifications push pour Android avec Azure
L'implémentation sur Android est un peu plus complexe et nécessite la mise en œuvre d'un
Service spécifique.
Tout d'abord, vérifions si notre appareil est capable de recevoir des notifications push, et si oui,
enregistrez-le avec Google. Cela peut être fait avec ce code dans notre fichier MainActivity.cs .
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App());
}
Les SenderIDs se trouvent dans le code ci-dessous et correspondent au numéro de projet que
vous obtenez depuis le tableau de bord du développeur Google afin de pouvoir envoyer des
messages Push.
using Android.App;
using Android.Content;
using Gcm.Client;
using Java.Lang;
using System;
using WindowsAzure.Messaging;
using XamarinNotifications.Helpers;
// These attributes are to register the right permissions for our app concerning push messages
[assembly: Permission(Name = "com.versluisit.xamarinnotifications.permission.C2D_MESSAGE")]
https://riptutorial.com/fr/home 119
[assembly: UsesPermission(Name =
"com.versluisit.xamarinnotifications.permission.C2D_MESSAGE")]
[assembly: UsesPermission(Name = "com.google.android.c2dm.permission.RECEIVE")]
namespace XamarinNotifications.Droid.PlatformSpecifics
{
// These attributes belong to the BroadcastReceiver, they register for the right intents
[BroadcastReceiver(Permission = Constants.PERMISSION_GCM_INTENTS)]
[IntentFilter(new[] { Constants.INTENT_FROM_GCM_MESSAGE },
Categories = new[] { "com.versluisit.xamarinnotifications" })]
[IntentFilter(new[] { Constants.INTENT_FROM_GCM_REGISTRATION_CALLBACK },
Categories = new[] { "com.versluisit.xamarinnotifications" })]
[IntentFilter(new[] { Constants.INTENT_FROM_GCM_LIBRARY_RETRY },
Categories = new[] { "com.versluisit.xamarinnotifications" })]
[Service] // Don't forget this one! This tells Xamarin that this class is a Android
Service
public class PushHandlerService : GcmServiceBase
{
// TODO add your own access key
private string _connectionString =
ConnectionString.CreateUsingSharedAccessKeyWithListenAccess(
new Java.Net.URI("sb://xamarinnotifications-ns.servicebus.windows.net/"), "<your
key here>");
if (intent.Extras.ContainsKey("title"))
title = intent.Extras.GetString("title");
if (!string.IsNullOrEmpty(messageText))
CreateNotification(title, messageText);
}
https://riptutorial.com/fr/home 120
private void CreateNotification(string title, string desc)
{
// First we make sure our app will start when the notification is pressed
const int pendingIntentId = 0;
const int notificationId = 0;
stackBuilder.AddParentStack(Class.FromType(typeof(MainActivity)));
stackBuilder.AddNextIntent(startupIntent);
var pendingIntent =
stackBuilder.GetPendingIntent(pendingIntentId, PendingIntentFlags.OneShot);
// Here we start building our actual notification, this has some more
// interesting customization options!
var builder = new Notification.Builder(this)
.SetContentIntent(pendingIntent)
.SetContentTitle(title)
.SetContentText(desc)
.SetSmallIcon(Resource.Drawable.icon);
Settings.DeviceToken = registrationId;
// TODO set some tags here if you want and supply them to the Register method
var tags = new string[] { };
hub.Register(registrationId, tags);
}
https://riptutorial.com/fr/home 121
hub.UnregisterAll(registrationId);
}
}
}
Sur Windows Phone, le code ci-dessous doit être implémenté pour commencer à travailler avec
les notifications push. Cela peut être trouvé dans le fichier App.xaml.cs
https://riptutorial.com/fr/home 122
Un exemple de notification push peut ressembler à ceci:
https://riptutorial.com/fr/home 123
Chapitre 30: Notifications push
Remarques
S'abonner - Vous vous inscrivez sur votre téléphone / client pour recevoir des notifications
GCM - Google Cloud Messaging est très similaire à APNS. Google est le seul à pouvoir envoyer
directement des notifications push. Nous enregistrons donc d'abord notre application dans GCM
et remettons notre jeton à AWS SNS. SNS gère tous les problèmes complexes liés à GCM et à
l'envoi des données.
Examples
Exemple iOS
//variable to set-up the style of notifications you want, iOS supports 3 types
https://riptutorial.com/fr/home 124
null );
//both of these methods are in iOS, we have to override them and set them up
//to allow push notifications
// This contains the registered push notification token stored on the phone.
var deviceToken = token.Description.Replace("<", "").Replace(">", "").Replace(" ",
"");
if (!string.IsNullOrEmpty(deviceToken))
{
//register with SNS to create an endpoint ARN, this means AWS can message your
phone
var response = await snsClient.CreatePlatformEndpointAsync(
new CreatePlatformEndpointRequest
{
Token = deviceToken,
PlatformApplicationArn = "yourARNwouldgohere" /* insert your platform
application ARN here */
});
//AWS lets you create topics, so use subscribe your app to a topic, so you can
easily send out one push notification to all of your users
var subscribeResponse = await snsClient.SubscribeAsync(new SubscribeRequest
{
TopicArn = "YourTopicARN here",
Endpoint = endpoint,
Protocol = "application"
});
https://riptutorial.com/fr/home 125
Chapitre 31: OAuth2
Examples
Authentification à l'aide du plugin
1. Tout d'abord, allez dans Outils > Gestionnaire de packages NuGet > Console du
gestionnaire de packages .
https://riptutorial.com/fr/home 126
3. Maintenant tout le fichier est automatiquement créé.
https://riptutorial.com/fr/home 127
Chapitre 32: Page Xamarin.Forms
Examples
TabbedPage
Une TabbedPage est similaire à une NavigationPage en ce sens qu'elle permet et gère une
navigation simple entre plusieurs objets Page enfant. La différence est que, en règle générale,
chaque plate-forme affiche une sorte de barre en haut ou en bas de l’écran qui affiche la plupart,
voire la totalité, des objets enfant disponibles. Dans les applications Xamarin.Forms, une
TabbedPage est généralement utile lorsque vous disposez d'un petit nombre prédéfini de pages
entre lesquelles les utilisateurs peuvent naviguer, comme un menu ou un assistant simple pouvant
être placé en haut ou en bas de l'écran.
XAML
Code
https://riptutorial.com/fr/home 128
}
};
var tabbedPage = new TabbedPage {
Children = { page1, page2 }
};
Contenu de la page
XAML
Code
https://riptutorial.com/fr/home 129
MasterDetailPage
XAML
Code
TextColor = Color.Black,
Text = "This is the Master page.",
HorizontalOptions = LayoutOptions.Center,
https://riptutorial.com/fr/home 130
VerticalOptions = LayoutOptions.Center
}
},
Detail = new ContentPage {
Content = new Label {
Title = "Detail",
Text = "This is the Detail page.",
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center
}
}
};
https://riptutorial.com/fr/home 131
Chapitre 33: Polices personnalisées dans les
styles
Remarques
Ressources à regarder:
• Styles Xamarin
• Utilisation de polices personnalisées sur iOS et Android avec Xamarin.Forms
• Renderers personnalisés
• Dictionnaires de ressources
• Propriétés attachées
Examples
Accéder aux polices personnalisées dans Syles
Dans le monde mobile, votre application doit être jolie et se démarquer des autres applications.
L'un de ces caractères est les polices personnalisées utilisées dans l'application.
Grâce à la prise en charge de XAML Styling dans Xamarin.Forms, vous venez de créer un style
de base pour toutes les étiquettes avec vos polices personnalisées.
Pour inclure des polices personnalisées dans votre projet iOS et Android, suivez le guide dans
Utilisation de polices personnalisées sur iOS et Android avec le message Xamarin.Forms écrit par
Gerald.
Déclarez le style dans la section des ressources du fichier App.xaml. Cela rend tous les styles
globalement visibles.
Dans Gerald post ci-dessus, nous devons utiliser la propriété StyleId, mais ce n'est pas une
propriété pouvant être liée, donc pour l'utiliser dans Style Setter, vous devez créer une propriété
attachable:
https://riptutorial.com/fr/home 132
public static String GetStyleId(BindableObject bindable) =>
(String)bindable.GetValue(StyleIdProperty);
<Application.Resources>
<ResourceDictionary>
<Style x:Key="LabelStyle" TargetType="Label">
<Setter Property="FontFamily" Value="Metric Bold" />
<Setter Property="h:FontHelper.StyleId" Value="Metric-Bold" />
</Style>
</ResourceDictionary>
</Application.Resources>
</Application>
Selon l'article ci-dessus, nous devons créer un moteur de rendu personnalisé pour Label qui hérite
de la plateforme LabelRenderer On Android.
https://riptutorial.com/fr/home 133
Vous pouvez maintenant obtenir du style dans le balisage de votre page:
Ou appliquer un style à toutes les étiquettes de la page en créant Style basé sur LabesStyle
<ContentPage.Resources>
<ResourceDictionary>
<Style TargetType="Label" BasedOn={StaticResource LabelStyle}>
</Style>
</ResourceDictionary>
</ContentPage.Resources>
</ContentPage>
https://riptutorial.com/fr/home 134
Chapitre 34: Pourquoi utiliser les formulaires
Xamarin et quand utiliser les formulaires
Xamarin
Remarques
Vous pouvez vous référer à la documentation officielle de Xamarin Forms pour en savoir plus:
https://www.xamarin.com/forms
Examples
Pourquoi utiliser les formulaires Xamarin et quand utiliser les formulaires
Xamarin
Xamarin devient de plus en plus populaire - il est difficile de décider quand utiliser Xamarin.Forms
et quand Xamarin.Platform (donc Xamarin.iOS et Xamarin.Android).
Tout d'abord, vous devez savoir pour quel type d'applications vous pouvez utiliser
Xamarin.Forms:
1. Prototypes - pour visualiser comment votre application regardera les différents appareils.
3. Les applications où le partage de code est crucial - plus important que l'interface utilisateur.
4. Applications où les données affichées sont plus importantes que les fonctionnalités
avancées
1. Qui sera responsable du développement des applications - si votre équipe est composée de
développeurs mobiles expérimentés, ils seront en mesure de gérer facilement les
Xamarin.Forms. Mais si vous avez un développeur par plate-forme (développement natif),
les formulaires peuvent être plus difficiles.
3. Le développement rapide est parfois très important - pour réduire les coûts et les délais,
vous pouvez décider d'utiliser des formulaires.
https://riptutorial.com/fr/home 135
4. Lorsque vous développez des applications d'entreprise sans aucune fonctionnalité avancée,
il est préférable d'utiliser Xamarin.Forms - il vous permet de partager le code de mode et
non l'événement dans la zone mobile, mais en général. Certaines parties du code peuvent
être partagées sur plusieurs plates-formes.
1. Vous devez créer des fonctionnalités personnalisées et accéder à des API spécifiques à la
plate-forme
2. Vous devez créer une interface utilisateur personnalisée pour l'application mobile
3. Lorsque certaines fonctionnalités ne sont pas prêtes pour Xamarin.Forms (comme certains
comportements spécifiques sur le périphérique mobile)
Lire Pourquoi utiliser les formulaires Xamarin et quand utiliser les formulaires Xamarin en ligne:
https://riptutorial.com/fr/xamarin-forms/topic/6869/pourquoi-utiliser-les-formulaires-xamarin-et-
quand-utiliser-les-formulaires-xamarin
https://riptutorial.com/fr/home 136
Chapitre 35: Renderers personnalisés
Examples
Rendu personnalisé pour ListView
Par exemple, nous devons désactiver le défilement dans ListView . Sur iOS, ListView est défilable
même si tous les éléments sont placés à l'écran et que l'utilisateur ne peut pas faire défiler la liste.
Xamarin.Forms.ListView ne gère pas ce paramètre. Dans ce cas, un moteur de rendu vient en aide.
Tout d'abord, nous devons créer un contrôle personnalisé dans le projet PCL, qui déclarera une
propriété obligatoire pouvant être liée:
iOS:
Control.ScrollEnabled = superListView.IsScrollingEnable;
}
https://riptutorial.com/fr/home 137
}
}
Et Android (la liste d'Android n'a pas de défilement si tous les éléments sont placés à l'écran, donc
nous ne désactiverons pas le défilement, mais nous pouvons toujours utiliser les propriétés
natives):
Element propriété SuperListView du moteur de rendu est mon contrôle SuperListView du projet PCL.
Control propriété de Control du rendu est un contrôle natif. Android.Widget.ListView pour Android et
UIKit.UITableView pour iOS.
<ContentPage x:Name="Page"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:SuperForms.Controls;assembly=SuperForms.Controls"
x:Class="SuperForms.Samples.SuperListViewPage">
https://riptutorial.com/fr/home 138
public ObservableCollection<string> Items
{
get { return _items; }
set
{
_items = value;
OnPropertyChanged();
}
}
public SuperListViewPage()
{
var list = new SuperListView();
InitializeComponent();
L'aide du moteur de rendu personnalisé permet d'ajouter de nouvelles propriétés et de les rendre
différemment dans une plate-forme native qui ne peut pas l'être autrement via un code partagé.
Dans cet exemple, nous allons ajouter un rayon et une ombre à une vue de boîte.
Tout d'abord, nous devons créer un contrôle personnalisé dans le projet PCL, qui déclarera une
propriété obligatoire pouvant être liée:
namespace Mobile.Controls
{
public class ExtendedBoxView : BoxView
{
/// <summary>
/// Respresents the background color of the button.
/// </summary>
public static readonly BindableProperty BorderRadiusProperty =
BindableProperty.Create<ExtendedBoxView, double>(p => p.BorderRadius, 0);
https://riptutorial.com/fr/home 139
set { SetValue(StrokeProperty, value); }
}
iOS:
Layer.MasksToBounds = true;
Layer.CornerRadius = (float)((ExtendedBoxView)this.Element).BorderRadius / 2.0f;
}
https://riptutorial.com/fr/home 140
nfloat radius = (nfloat)roundedBoxView.BorderRadius;
radius = (nfloat)Math.Max(0, Math.Min(radius, Math.Max(rCorner.Height / 2,
rCorner.Width / 2)));
}
}
Encore une fois, vous pouvez personnaliser comme vous le souhaitez dans la méthode de dessin.
/// <summary>
///
/// </summary>
/// <param name="e"></param>
protected override void OnElementChanged(ElementChangedEventArgs<BoxView> e)
{
base.OnElementChanged(e);
SetWillNotDraw(false);
Invalidate();
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected override void OnElementPropertyChanged(object sender,
System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == ExtendedBoxView.BorderRadiusProperty.PropertyName)
{
Invalidate();
}
}
https://riptutorial.com/fr/home 141
/// <summary>
///
/// </summary>
/// <param name="canvas"></param>
public override void Draw(Canvas canvas)
{
var box = Element as ExtendedBoxView;
base.Draw(canvas);
Paint myPaint = new Paint();
myPaint.SetStyle(Paint.Style.Stroke);
myPaint.StrokeWidth = (float)box.StrokeThickness;
myPaint.SetARGB(convertTo255ScaleColor(box.Color.A),
convertTo255ScaleColor(box.Color.R), convertTo255ScaleColor(box.Color.G),
convertTo255ScaleColor(box.Color.B));
myPaint.SetShadowLayer(20, 0, 5, Android.Graphics.Color.Argb(100, 0, 0, 0));
SetLayerType(Android.Views.LayerType.Software, myPaint);
/// <summary>
///
/// </summary>
/// <param name="color"></param>
/// <returns></returns>
private int convertTo255ScaleColor(double color)
{
return (int) Math.Ceiling(color * 255);
}
}
Le XAML:
Nous faisons d'abord référence à notre contrôle avec l'espace de noms que nous avons défini
précédemment.
xmlns:Controls="clr-namespace:Mobile.Controls"
Nous utilisons ensuite le contrôle comme suit et utilisons les propriétés définies au début:
<Controls:ExtendedBoxView
x:Name="search_boxview"
Color="#444"
https://riptutorial.com/fr/home 142
BorderRadius="5"
HorizontalOptions="CenterAndExpand"
/>
if (renderer == null)
{
renderer = Platform.CreateRenderer(visualElement);
Platform.SetRenderer(visualElement, renderer);
}
using Xamarin.Forms;
namespace ProjectNamespace
{
public class ExtendedFrame : Frame
{
/// <summary>
/// The corner radius property.
/// </summary>
public static readonly BindableProperty CornerRadiusProperty =
BindableProperty.Create("CornerRadius", typeof(double), typeof(ExtendedFrame),
0.0);
/// <summary>
/// Gets or sets the corner radius.
/// </summary>
public double CornerRadius
{
get { return (double)GetValue(CornerRadiusProperty); }
set { SetValue(CornerRadiusProperty, value); }
}
}
}
using ProjectNamespace;
using ProjectNamespace.iOS;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
https://riptutorial.com/fr/home 143
public class ExtendedFrameRenderer : FrameRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
{
base.OnElementChanged(e);
if (Element != null)
{
Layer.MasksToBounds = true;
Layer.CornerRadius = (float)(Element as ExtendedFrame).CornerRadius;
}
}
if (e.PropertyName == ExtendedFrame.CornerRadiusProperty.PropertyName)
{
Layer.CornerRadius = (float)(Element as ExtendedFrame).CornerRadius;
}
}
}
}
Si vous voulez l'utiliser dans une partie XAML, n'oubliez pas d'écrire ceci:
xmlns:controls="clr-namespace:ProjectNamespace;assembly:ProjectNamespace"
après
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
<controls:ExtendedFrame
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand"
BackgroundColor="Gray"
CornerRadius="35.0">
<Frame.Content>
<Label
Text="MyText"
TextColor="Blue"/>
</Frame.Content>
</controls:ExtendedFrame>
https://riptutorial.com/fr/home 144
public class RoundedBoxView : BoxView
{
public static readonly BindableProperty CornerRadiusProperty =
BindableProperty.Create("CornerRadius", typeof(double), typeof(RoundedEntry),
default(double));
https://riptutorial.com/fr/home 145
var rect = new Rect();
var paint = new Paint
{
Color = Xamarin.Forms.Color.FromHex(box.FillColor).ToAndroid(),
AntiAlias = true,
};
GetDrawingRect(rect);
if (Element != null)
{
Layer.CornerRadius = (float)(Element as RoundedBoxView).CornerRadius;
Layer.BackgroundColor = Color.FromHex((Element as
RoundedBoxView).FillColor).ToCGColor();
}
}
if (Element != null)
{
Layer.CornerRadius = (float)(Element as RoundedBoxView).CornerRadius;
Layer.BackgroundColor = (Element as RoundedBoxView).FillColor.ToCGColor();
}
}
}
}
https://riptutorial.com/fr/home 146
Chapitre 36: Services de dépendance
Remarques
Accéder à l'API spécifique à la plate-forme à partir du projet PCL ou Shared.
Examples
Accéder à la caméra et à la galerie.
https://riptutorial.com/fr/home 147
Chapitre 37: Test d'unité
Examples
Test des modèles de vue
Avant de commencer...
En termes de couches d'application, votre ViewModel est une classe contenant toute la logique
métier et les règles permettant à l'application de faire ce qu'elle doit selon les besoins. Il est
également important de le rendre le plus indépendant possible, en réduisant les références à
l'interface utilisateur, à la couche de données, aux fonctionnalités natives et aux appels d'API, etc.
Tous ces éléments permettent de tester votre machine virtuelle.
En bref, votre ViewModel:
• Ne devrait pas dépendre des classes de l'interface utilisateur (vues, pages, styles,
événements);
• Ne devrait pas utiliser les données statiques d'une autre classe (autant que vous le pouvez);
• Doit implémenter la logique métier et préparer les données sur l'interface utilisateur;
• Devrait utiliser d'autres composants (base de données, HTTP, spécifique à l'interface
utilisateur) via des interfaces en cours de résolution à l'aide de l'injection de dépendances.
Votre ViewModel peut également avoir les propriétés d'un autre type de machine
virtuelle. Par exemple, ContactsPageViewModel aura la propriété du type de collection
comme ObservableCollection<ContactListItemViewModel>
Besoins de l'entreprise
Disons que nous avons les fonctionnalités suivantes à implémenter:
As an unauthorized user
I want to log into the app
So that I will access the authorized features
Après avoir clarifié la user story, nous avons défini les scénarios suivants:
https://riptutorial.com/fr/home 148
Given the user is on Login screen
When the user enters ' ' as username
And the user enters 'pass' as password
And the user taps the Login button
Then the app shows an error message saying 'Please, enter correct username and password'
And the app doesn't make an API call for authentication
Nous resterons avec seulement ces deux scénarios. Bien sûr, il devrait y avoir beaucoup plus de
cas et vous devriez tous les définir avant le codage réel, mais il est assez suffisant pour nous
familiariser maintenant avec les tests unitaires des modèles de vue.
Suivons l'approche TDD classique et commençons par écrire une classe vide en cours de test.
Ensuite, nous écrirons des tests et les rendrons verts en implémentant la fonctionnalité métier.
Cours communs
public abstract class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
Prestations de service
Vous souvenez-vous que notre modèle de vue ne doit pas utiliser directement les classes UI et
HTTP? Vous devez les définir comme des abstractions à la place et ne pas dépendre des détails
de l'implémentation .
/// <summary>
/// Provides authentication functionality.
/// </summary>
public interface IAuthenticationService
{
/// <summary>
/// Tries to authenticate the user with the given credentials.
/// </summary>
/// <param name="userName">UserName</param>
/// <param name="password">User's password</param>
/// <returns>true if the user has been successfully authenticated</returns>
Task<bool> Login(string userName, string password);
}
/// <summary>
/// UI-specific service providing abilities to show alert messages.
/// </summary>
public interface IAlertService
{
/// <summary>
https://riptutorial.com/fr/home 149
/// Show an alert message to the user.
/// </summary>
/// <param name="title">Alert message title</param>
/// <param name="message">Alert message text</param>
Task ShowAlert(string title, string message);
}
https://riptutorial.com/fr/home 150
OnPropertyChanged();
}
}
}
Nous avons défini deux propriétés de string et une commande à lier sur l'interface utilisateur.
Nous ne décrirons pas comment créer une classe de page, un balisage XAML et lier ViewModel à
cette rubrique car ils n'ont rien de spécifique.
Des tests
Maintenant, écrivons quelques tests en fonction des cas d’utilisation listés ci-dessus. Tout d'abord,
vous devez créer un nouvel assembly (juste une bibliothèque de classes ou sélectionner un projet
de test spécial si vous souhaitez utiliser les outils de test unitaire Microsoft). Nommez-le quelque
chose comme ProjectName.Tests et ajoutez une référence à votre projet PCL original.
https://riptutorial.com/fr/home 151
Dans cet exemple, je vais utiliser NUnit et Moq, mais vous pouvez continuer avec tous les tests de
votre choix. Il n'y aura rien de spécial avec eux.
[TestFixture]
public class LoginPageViewModelTest
{
}
Tests d'écriture
Voici les méthodes de test pour les deux premiers scénarios. Essayez de conserver 1 méthode de
test par 1 résultat attendu et de ne pas tout vérifier en un seul test. Cela vous aidera à recevoir
des rapports plus clairs sur ce qui a échoué dans le code.
[TestFixture]
public class LoginPageViewModelTest
{
private readonly Mock<IAuthenticationService> authenticationServiceMock =
new Mock<IAuthenticationService>();
private readonly Mock<IAlertService> alertServiceMock =
new Mock<IAlertService>();
[TestCase("user", "pass")]
public void LogInWithValidCreds_LoadingIndicatorShown(string userName, string password)
{
LoginPageViewModel model = CreateViewModelAndLogin(userName, password);
Assert.IsTrue(model.IsLoading);
}
[TestCase("user", "pass")]
public void LogInWithValidCreds_AuthenticationRequested(string userName, string password)
{
CreateViewModelAndLogin(userName, password);
[TestCase("", "pass")]
[TestCase(" ", "pass")]
[TestCase(null, "pass")]
public void LogInWithEmptyuserName_AuthenticationNotRequested(string userName, string
password)
{
CreateViewModelAndLogin(userName, password);
https://riptutorial.com/fr/home 152
string message)
{
CreateViewModelAndLogin(userName, password);
model.UserName = userName;
model.Password = password;
model.LoginCommand.Execute(null);
return model;
}
}
Et c'est reparti:
Maintenant, l'objectif est d'écrire une implémentation correcte pour la méthode de Login de
ViewModel et c'est tout.
https://riptutorial.com/fr/home 153
}
}
Maintenant, vous pouvez continuer à couvrir votre code avec de nouveaux tests le rendant plus
stable et sans risque de régression.
https://riptutorial.com/fr/home 154
Chapitre 38: Test d'unité BDD dans
Xamarin.Forms
Remarques
• Le conteneur / résolveur DI que nous utilisons en interne dans cette bibliothèque est
Autofac.
• Le framework de test est NUnit 3x.
• Vous devriez pouvoir utiliser cette bibliothèque avec n'importe quel framework
Xamarin.Forms
• Source et exemple de projet disponible ici
Examples
Spécflow simple pour tester les commandes et la navigation avec NUnit Test
Runner
Xamarin fournit également des tests d'interface utilisateur impressionnants avec l'offre
Xamarin.TestCloud , mais lorsque vous souhaitez implémenter des pratiques de développement
BDD et que vous avez la possibilité de tester ViewModels et les commandes, tout en fonctionnant
à peu de frais sur un serveur de test local ou sur un serveur de construction, construit de manière.
J'ai développé une bibliothèque qui permet d'utiliser Specflow avec Xamarin.Forms pour
implémenter facilement vos fonctionnalités depuis vos définitions de scénarios jusqu'à ViewModel,
indépendamment de tout framework MVVM utilisé pour l'application (tels que XLabs , MVVMCross
, Prism ).
Usage:
• Si vous ne l'avez pas encore, installez l'extension visuelle studio specflow à partir d'ici (ou de
votre IDE studio visuel): https://visualstudiogallery.msdn.microsoft.com/c74211e7-cb6e-4dfa-
855d-df0ad4a37dd6
• Ajoutez une bibliothèque de classes à votre projet Xamarin.Forms. C'est votre projet de test.
https://riptutorial.com/fr/home 155
• Ajoutez le package SpecFlow.Xamarin.Forms de nuget à vos projets de test.
• Ajoutez une classe à votre projet de test qui hérite de 'TestApp', et enregistrez vos paires
views / viewmodels, ainsi que tout enregistrement DI, comme indiqué ci-dessous:
• Ajoutez une classe SetupHook à votre projet de test afin d'ajouter vos hooks Specflow. Vous
devrez lancer l'application de test comme indiqué ci-dessous, en indiquant la classe que
vous avez créée ci-dessus et le modèle de vue initial de votre application:
[Binding]
public class SetupHooks : TestSetupHooks
{
/// <summary>
/// The before scenario.
/// </summary>
[BeforeScenario]
public void BeforeScenario()
{
// bootstrap test app with your test app and your starting viewmodel
new TestAppBootstrap().RunApplication<DemoAppTest, MainViewModel>();
}
}
• Vous devrez ajouter un bloc catch à votre xamarin.forms views codebehind afin d'ignorer le
framework xamarin.forms vous obligeant à exécuter l'application ui (ce que nous ne voulons
pas faire):
public YourView()
{
try
{
InitializeComponent();
}
catch (InvalidOperationException soe)
{
if (!soe.Message.Contains("MUST"))
throw;
}
https://riptutorial.com/fr/home 156
}
• Ajouter une fonctionnalité de spécification à votre projet (en utilisant les modèles vs specflow
fournis avec l'extension vs specflow)
• Utilisez les services de navigation et les assistants pour naviguer, exécuter des commandes
et tester vos modèles de vue:
[Binding]
public class GeneralSteps : TestStepBase
{
public GeneralSteps(ScenarioContext scenarioContext)
: base(scenarioContext)
{
// you need to instantiate your steps by passing the scenarioContext to the base
}
Resolver.Instance.Resolve<INavigationService>().CurrentViewModelType.ShouldEqualType<MainViewModel>();
Pour ajouter au premier exemple, afin de tester les instructions de navigation qui se produisent
dans l'application, nous devons fournir le ViewModel avec un crochet à la navigation. Pour y
parvenir:
https://riptutorial.com/fr/home 157
• Le framework de test le récupérera et gérera la navigation interne
• Vous pouvez utiliser n'importe quel framework MVVM pour votre application (comme XLabs
, MVVMCross , Prism , etc.) . Tant que l'interface IViewModel est implémentée dans votre
ViewModel, le framework le récupérera.
https://riptutorial.com/fr/home 158
Chapitre 39: Travailler avec des bases de
données locales
Examples
Utilisation de SQLite.NET dans un projet partagé
SQLite.NET est une bibliothèque open source qui permet d'ajouter le support des bases de
données locales à l'aide de SQLite version 3 dans un projet Xamarin.Forms .
Les étapes ci-dessous montrent comment inclure ce composant dans un Xamarin.Forms partagé
Xamarin.Forms :
2. Chaque table qui sera incluse dans la base de données doit être modélisée en tant que
classe dans le projet partagé. Une table est définie en ajoutant au moins deux attributs dans
la classe: Table (pour la classe) et PrimaryKey (pour une propriété).
Pour cet exemple, une nouvelle classe nommée Song est ajoutée au projet partagé, défini comme
suit:
using System;
using SQLite;
namespace SongsApp
{
[Table("Song")]
public class Song
{
[PrimaryKey]
public string ID { get; set; }
public string SongName { get; set; }
public string SingerName { get; set; }
}
}
3. Ensuite, ajoutez une nouvelle classe appelée Database , qui hérite de la classe
SQLiteConnection (incluse dans SQLite.cs). Dans cette nouvelle classe, le code d'accès à la
base de données, la création des tables et les opérations CRUD pour chaque table sont
définis. Exemple de code est indiqué ci-dessous:
using System;
using System.Linq;
using System.Collections.Generic;
using SQLite;
namespace SongsApp
{
https://riptutorial.com/fr/home 159
public class BaseDatos : SQLiteConnection
{
public BaseDatos(string path) : base(path)
{
Initialize();
}
void Initialize()
{
CreateTable<Song>();
}
4. Comme vous avez pu le voir à l'étape précédente, le constructeur de notre classe Database
contient un paramètre path , qui représente l'emplacement du fichier qui stocke le fichier de
base de données SQLite. Un objet de Database statique peut être déclaré dans App.cs Le path
est spécifique à la plate-forme:
public App ()
{
string dbFile = "SongsDB.db3";
#if __ANDROID__
string docPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
var dbPath = System.IO.Path.Combine(docPath, dbFile);
#else
#if __IOS__
string docPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
string libPath = System.IO.Path.Combine(docPath, "..", "Library");
https://riptutorial.com/fr/home 160
var dbPath = System.IO.Path.Combine(libPath, dbFile);
#else
var dbPath = System.IO.Path.Combine(ApplicationData.Current.LocalFolder.Path, dbFile);
#endif
#endif
DB = new Database(dbPath);
5. Maintenant, appelez simplement l'objet DB via la classe App chaque fois que vous devez
effectuer une opération CRUD sur la table Songs . Par exemple, pour insérer un nouveau Song
après que l'utilisateur a cliqué sur un bouton, vous pouvez utiliser le code suivant:
App.DB.AddSong(song);
}
1. Les étapes ci-dessous montrent comment inclure ce composant dans un projet partagé
Xamarin.Forms: ajouter des packages dans (pcl, Andriod, Windows, Ios) Ajouter des
références Cliquez sur Gérer les packages Nuget -> cliquez sur Parcourir pour installer
SQLite.Net.Core- PCL , SQLite Net Extensions après l’installation est terminée
using SQLite.Net.Attributes;
namespace DatabaseEmployeeCreation.SqlLite
{
public class Employee
{
[PrimaryKey,AutoIncrement]
public int Eid { get; set; }
public string Ename { get; set; }
public string Address { get; set; }
public string phonenumber { get; set; }
public string email { get; set; }
}
}
https://riptutorial.com/fr/home 161
3. Ajouter une interface ISQLite
using SQLite.Net;
//using SQLite.Net;
namespace DatabaseEmployeeCreation.SqlLite.ViewModel
{
public interface ISQLite
{
SQLiteConnection GetConnection();
}
}
4. Créez une classe unique pour les logiques de base de données et les méthodes ci-dessous
sont utilisées.
public DatabaseLogic()
{
database = DependencyService.Get<ISQLite>().GetConnection();
// create the tables
database.CreateTable<Employee>();
}
https://riptutorial.com/fr/home 162
}
else
{
return database.Insert(item);
}
}
}
</StackLayout>
</ContentPage>
EmployeeRegistration.cs
using DatabaseEmployeeCreation.SqlLite.ViewModel;
using DatabaseEmployeeCreation.SqlLite.Views;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
https://riptutorial.com/fr/home 163
using Xamarin.Forms;
namespace DatabaseEmployeeCreation.SqlLite
{
public partial class EmployeeRegistration : ContentPage
{
private int empid;
private Employee obj;
public EmployeeRegistration()
{
InitializeComponent();
//AddressEntry.Text = obj.Address;
//emailEntry.Text = obj.email;
//nameEntry.Text = obj.Ename;
//phonenumberEntry.Text = obj.phonenumber;
https://riptutorial.com/fr/home 164
Employee empupdate = new Employee(); //updateing Values
empupdate.Address = AddressEntry.Text;
empupdate.email = emailEntry.Text;
App.Database.SaveItem(empupdate);
Navigation.PushModalAsync(new EmployeeRegistration());
}
}
//void deleteClicked(object sender, EventArgs e)
//{
// var emp = (Employee)BindingContext;
// App.Database.DeleteItem(emp.Eid);
// this.Navigation.PopAsync();
//}
void DetailsClicked(object sender, EventArgs e)
{
var empcancel = (Employee)BindingContext;
this.Navigation.PushAsync(new EmployeeDetails());
}
// void speakClicked(object sender, EventArgs e)
// {
// var empspek = (Employee)BindingContext;
// //DependencyService.Get<ITextSpeak>().Speak(empspek.Address + " " +
empspek.Ename);
// }
}
}
using DatabaseEmployeeCreation;
using DatabaseEmployeeCreation.SqlLite;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace DatabaseEmployeeCreation.SqlLite.Views
{
public partial class EmployeeDetails : ContentPage
{
ListView lv = new ListView();
IEnumerable<Employee> lst;
public EmployeeDetails()
{
https://riptutorial.com/fr/home 165
InitializeComponent();
displayemployee();
}
Text = "Details",
BackgroundColor = Color.Blue,
};
btn.Clicked += Btn_Clicked;
//IEnumerable<Employee> lst = App.Database.GetItems();
//IEnumerable<Employee> lst1 = App.Database.GetItemsNotDone();
//IEnumerable<Employee> lst2 = App.Database.GetItemsNotDone();
Content = new StackLayout()
{
Children = { btn },
};
}
lv.ItemsSource = lst;
lv.HasUnevenRows = true;
lv.ItemTemplate = new DataTemplate(typeof(OptionsViewCell));
}
}
int empid;
Button btnEdit;
public OptionsViewCell()
{
}
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
if (this.BindingContext == null)
return;
https://riptutorial.com/fr/home 166
var lblAddress = new Label
{
BackgroundColor = Color.Yellow,
Text = obj.Address,
};
https://riptutorial.com/fr/home 167
Text = "Delete",
//WidthRequest = 15,
//HeightRequest = 20,
TextColor = Color.Red,
HorizontalOptions = LayoutOptions.EndAndExpand,
};
btnDelete.Clicked += BtnDelete_Clicked;
//btnDelete.PropertyChanged += BtnDelete_PropertyChanged;
https://riptutorial.com/fr/home 168
}
}
// App.Database.DeleteItem(eid);
//}
}
using System;
using Xamarin.Forms;
using System.IO;
using DatabaseEmployeeCreation.Droid;
using DatabaseEmployeeCreation.SqlLite.ViewModel;
using SQLite;
using SQLite.Net;
[assembly: Dependency(typeof(SQLiteEmployee_Andriod))]
namespace DatabaseEmployeeCreation.Droid
{
public class SQLiteEmployee_Andriod : ISQLite
{
public SQLiteEmployee_Andriod()
{
}
https://riptutorial.com/fr/home 169
// var s =
Forms.Context.Resources.OpenRawResource(Resource.Raw.EmployeeSQLite); // RESOURCE NAME ###
/// <summary>
/// helper method to get the database out of /raw/ and into the user filesystem
/// </summary>
void ReadWriteStream(Stream readStream, Stream writeStream)
{
int Length = 256;
Byte[] buffer = new Byte[Length];
int bytesRead = readStream.Read(buffer, 0, Length);
// write the required bytes
while (bytesRead > 0)
{
writeStream.Write(buffer, 0, bytesRead);
bytesRead = readStream.Read(buffer, 0, Length);
}
readStream.Close();
writeStream.Close();
}
}
}
J'espère que cet exemple ci-dessus est très facile, j'ai expliqué
https://riptutorial.com/fr/home 170
forms/topic/5997/travailler-avec-des-bases-de-donnees-locales
https://riptutorial.com/fr/home 171
Chapitre 40: Travailler avec des cartes
Remarques
Si vous envisagez d'exécuter votre projet sur un autre ordinateur, vous devrez générer une
nouvelle clé API, car les empreintes SHA-1 ne correspondront pas aux différentes machines de
génération.
Vous pouvez explorer le projet, décrit dans l'exemple Ajouter une carte dans Xamarin.Forms ici
Examples
Ajouter une carte dans Xamarin.Forms (Xamarin Studio)
Vous pouvez simplement utiliser les API de carte natives sur chaque plate-forme avec Xamarin
Forms. Il vous suffit de télécharger le package Xamarin.Forms.Maps à partir de nuget et de
l'installer dans chaque projet (y compris le projet PCL).
projet iOS
Fichier AppDelegate.cs
[Register("AppDelegate")]
public partial class AppDelegate : Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
Xamarin.Forms.Forms.Init();
Xamarin.FormsMaps.Init();
LoadApplication(new App());
Projet Android
https://riptutorial.com/fr/home 172
Fichier MainActivity.cs
base.OnCreate(bundle);
Xamarin.Forms.Forms.Init(this, bundle);
Xamarin.FormsMaps.Init(this, bundle);
LoadApplication(new App());
}
}
Configuration de la plate-forme
Des étapes de configuration supplémentaires sont nécessaires sur certaines plates-formes avant
que la carte ne s'affiche.
projet iOS
Dans un projet iOS, il suffit d'ajouter 2 entrées à votre fichier Info.plist :
https://riptutorial.com/fr/home 173
Projet Android
Pour utiliser Google Maps, vous devez générer une clé API et l'ajouter à votre projet. Suivez les
instructions ci-dessous pour obtenir cette clé:
cd /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands
Où [NOM D'UTILISATEUR] est évidemment votre dossier d'utilisateur actuel. Vous devriez
obtenir quelque chose de similaire dans la sortie:
https://riptutorial.com/fr/home 174
Valid from: Thu Jun 30 10:22:00 EEST 2016 until: Sat Jun 23 10:22:00 EEST 2046
Certificate fingerprints:
MD5: 4E:49:A7:14:99:D6:AB:9F:AA:C7:07:E2:6A:1A:1D:CA
SHA1: 57:A1:E5:23:CE:49:2F:17:8D:8A:EA:87:65:44:C1:DD:1C:DA:51:95
SHA256:
70:E1:F3:5B:95:69:36:4A:82:A9:62:F3:67:B6:73:A4:DD:92:95:51:44:E3:4C:3D:9E:ED:99:03:09:9F:90:3F
4. Tout ce dont nous avons besoin dans cette sortie est l'empreinte du certificat SHA1. Dans
notre cas, cela équivaut à ceci:
57:A1:E5:23:CE:49:2F:17:8D:8A:EA:87:65:44:C1:DD:1C:DA:51:95
Copiez ou enregistrez quelque part cette clé. Nous en aurons besoin plus tard.
5. Accédez à Google Developers Console , dans notre cas, nous devons ajouter l' API Google
Maps Android , alors choisissez-la:
https://riptutorial.com/fr/home 175
6. Google vous demandera de créer un projet pour activer les API, suivez cette astuce et créez
le projet:
https://riptutorial.com/fr/home 176
7. Activez l'API Google Maps pour votre projet:
https://riptutorial.com/fr/home 177
Après avoir activé api, vous devez créer des informations d'identification pour votre
application. Suivez ce conseil:
https://riptutorial.com/fr/home 178
8. Sur la page suivante, choisissez la plate-forme Android, appuyez sur "Quelles sont les
références dont j'ai besoin?" Cliquez sur le bouton, créez un nom pour votre clé API, tapez
sur "Ajouter le nom et l’empreinte du package", entrez votre nom de package et votre
empreinte SHA1 à l’étape 4 et créez enfin une clé API:
https://riptutorial.com/fr/home 179
Pour trouver le nom de votre package dans Xamarin Studio, accédez à votre solution .Droid
-> AndroidManifest.xml:
https://riptutorial.com/fr/home 180
9. Après la création, copiez la nouvelle clé API (n'oubliez pas de cliquer sur le bouton
"Terminé") et collez-la dans votre fichier AndroidManifest.xml :
https://riptutorial.com/fr/home 181
Fichier AndroidManifest.xml
Vous devrez également activer certaines autorisations dans votre manifeste pour activer
certaines fonctionnalités supplémentaires:
https://riptutorial.com/fr/home 182
• Accès Emplacement Commandes supplémentaires
• Emplacement du mock d'accès
• État du réseau d'accès
• Accès Wifi State
• l'Internet
Bien que les deux dernières autorisations soient nécessaires pour télécharger des données
https://riptutorial.com/fr/home 183
Maps. Lisez les autorisations sur Android pour en savoir plus. C'est toutes les étapes pour la
configuration Android.
Projet PCL
Fichier MapExample.cs
MainPage = rootPage;
}
}
C'est tout. Maintenant, si vous exécutez votre application sur iOS ou Android, la carte s'affiche:
https://riptutorial.com/fr/home 184
Lire Travailler avec des cartes en ligne: https://riptutorial.com/fr/xamarin-
forms/topic/3917/travailler-avec-des-cartes
https://riptutorial.com/fr/home 185
Chapitre 41: Utilisation de ListViews
Introduction
Cette documentation explique comment utiliser les différents composants de Xamarin Forms
ListView
Examples
Tirez pour actualiser dans XAML et code derrière
Pour activer l'option Pull to Refresh dans ListView dans Xamarin, vous devez d'abord spécifier qu'il
s'agit de PullToRefresh activé, puis spécifier le nom de la commande à appeler lors de l' ListView :
itemListView.IsPullToRefreshEnabled = true;
itemListView.RefreshCommand = Refresh;
Ensuite, vous devez spécifier ce que la commande d' Refresh fait dans votre code derrière:
https://riptutorial.com/fr/home 186
Chapitre 42: Vues Xamarin.Forms
Examples
Bouton
Le bouton est probablement le contrôle le plus courant non seulement dans les applications
mobiles, mais aussi dans toutes les applications disposant d'une interface utilisateur. Le concept
d'un bouton a trop d'objectifs à énumérer ici. En règle générale cependant, vous utiliserez un
bouton pour permettre aux utilisateurs de lancer une action ou une opération dans votre
application. Cette opération peut inclure tout, de la navigation de base dans votre application, à la
soumission de données à un service Web quelque part sur Internet.
XAML
<Button
x:Name="MyButton"
Text="Click Me!"
TextColor="Red"
BorderColor="Blue"
VerticalOptions="Center"
HorizontalOptions="Center"
Clicked="Button_Clicked"/>
XAML Code-Behind
Code
https://riptutorial.com/fr/home 187
Sélecteur de date
Très souvent, dans les applications mobiles, il y aura une raison de traiter les dates. Lorsque vous
travaillez avec des dates, vous aurez probablement besoin d'une sorte de saisie utilisateur pour
sélectionner une date. Cela peut se produire lorsque vous travaillez avec une application de
planification ou de calendrier. Dans ce cas, il est préférable de fournir aux utilisateurs un contrôle
spécialisé leur permettant de sélectionner une date de manière interactive, plutôt que de
demander aux utilisateurs de saisir manuellement une date. C'est là que le contrôle DatePicker
est vraiment utile.
XAML
Code
https://riptutorial.com/fr/home 188
Entrée
La vue d'entrée permet aux utilisateurs de saisir une seule ligne de texte. Cette seule ligne de
texte peut être utilisée à des fins multiples, y compris la saisie de notes de base, d'informations
d'identification, d'URL, etc. Cette vue est une vue polyvalente, ce qui signifie que si vous avez
besoin de taper du texte normal ou que vous souhaitez masquer un mot de passe, tout se fait via
ce seul contrôle.
XAML
Code
https://riptutorial.com/fr/home 189
Éditeur
L'éditeur est très similaire à l'entrée en ce sens qu'il permet aux utilisateurs d'entrer du texte libre.
La différence est que l'éditeur permet une entrée multi-lignes alors que l'entrée n'est utilisée que
pour une entrée sur une seule ligne. L'entrée fournit également quelques propriétés
supplémentaires par rapport à l'éditeur pour permettre une personnalisation supplémentaire de la
vue.
XAML
<Editor HorizontalOptions="Fill"
VerticalOptions="Fill"
Keyboard="Chat"/>
Code
https://riptutorial.com/fr/home 190
Image
Les images sont des parties très importantes de toute application. Ils permettent d'injecter des
éléments visuels supplémentaires ainsi que des marques dans votre application. Sans oublier que
les images sont généralement plus intéressantes à regarder que du texte ou des boutons. Vous
pouvez utiliser une image en tant qu'élément autonome dans votre application, mais un élément
Image peut également être ajouté à d'autres éléments d'affichage, tels qu'un bouton.
XAML
Code
https://riptutorial.com/fr/home 191
Étiquette
Croyez-le ou non, le Label est l'une des classes View les plus cruciales, mais encore sous-
estimées, non seulement dans Xamarin.Forms, mais dans le développement de l'interface
utilisateur en général. Il est considéré comme une ligne de texte plutôt ennuyeuse, mais sans
cette ligne de texte, il serait très difficile de transmettre certaines idées à l'utilisateur. Les contrôles
d'étiquette peuvent être utilisés pour décrire ce que l'utilisateur doit entrer dans un contrôle
d'édition ou de saisie. Ils peuvent décrire une section de l'interface utilisateur et lui donner un
contexte. Ils peuvent être utilisés pour afficher le total dans une application de calculatrice. Oui,
l'étiquette est vraiment le contrôle le plus polyvalent de votre trousse à outils, qui ne suscite pas
toujours beaucoup d'attention, mais c'est le premier à être remarqué s'il n'y en a pas.
XAML
Code
https://riptutorial.com/fr/home 192
Lire Vues Xamarin.Forms en ligne: https://riptutorial.com/fr/xamarin-forms/topic/7369/vues-
xamarin-forms
https://riptutorial.com/fr/home 193
Chapitre 43: Xamarin Plugin
Examples
Share Plugin
XAML
</StackLayout>
C#
Cartes externes
Plug-ins de cartes externes Ouvrez des cartes externes pour accéder à une géolocalisation ou
une adresse spécifique. Option pour lancer avec l'option de navigation sur iOS aussi.
XAML
https://riptutorial.com/fr/home 194
<Button x:Name="navigateAddress" Text="Navigate to Address"/>
<Button x:Name="navigateLatLong" Text="Navigate to Lat|Long"/>
<Label Text=""/>
</StackLayout>
Code
namespace PluginDemo
{
public partial class ExternalMaps : ContentPage
{
public ExternalMaps()
{
InitializeComponent();
navigateLatLong.Clicked += (sender, args) =>
{
CrossExternalMaps.Current.NavigateTo("Space Needle", 47.6204, -122.3491);
};
Plugin Geolocator
XAML
</StackLayout>
Code
namespace PluginDemo
{
public partial class GeolocatorPage : ContentPage
{
public GeolocatorPage()
{
InitializeComponent();
buttonGetGPS.Clicked += async (sender, args) =>
https://riptutorial.com/fr/home 195
{
try
{
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 1000;
labelGPS.Text = "Getting gps";
if (position == null)
{
labelGPS.Text = "null gps :(";
return;
}
labelGPS.Text = string.Format("Time: {0} \nLat: {1} \nLong: {2}
\nAltitude: {3} \nAltitude Accuracy: {4} \nAccuracy: {5} \nHeading: {6} \nSpeed: {7}",
position.Timestamp, position.Latitude, position.Longitude,
position.Altitude, position.AltitudeAccuracy, position.Accuracy,
position.Heading, position.Speed);
}
catch //(Exception ex)
{
// Xamarin.Insights.Report(ex);
// await DisplayAlert("Uh oh", "Something went wrong, but don't worry we
captured it in Xamarin Insights! Thanks.", "OK");
}
};
https://riptutorial.com/fr/home 196
{
CrossGeolocator.Current.PositionChanged +=
CrossGeolocator_Current_PositionChanged;
CrossGeolocator.Current.PositionError +=
CrossGeolocator_Current_PositionError;
}
catch
{
}
}
Plugin Média
Prenez ou choisissez des photos et des vidéos à partir d'une API multi-plateforme.
XAML
https://riptutorial.com/fr/home 197
<Button x:Name="pickPhoto" Text="Pick Photo"/>
<Button x:Name="takeVideo" Text="Take Video"/>
<Button x:Name="pickVideo" Text="Pick Video"/>
<Label Text="Save to Gallery"/>
<Switch x:Name="saveToGallery" IsToggled="false" HorizontalOptions="Center"/>
<Label Text="Image will show here"/>
<Image x:Name="image"/>
<Label Text=""/>
</StackLayout>
Code
namespace PluginDemo
{
public partial class MediaPage : ContentPage
{
public MediaPage()
{
InitializeComponent();
takePhoto.Clicked += async (sender, args) =>
{
if (!CrossMedia.Current.IsCameraAvailable ||
!CrossMedia.Current.IsTakePhotoSupported)
{
await DisplayAlert("No Camera", ":( No camera avaialble.", "OK");
return;
}
try
{
var file = await CrossMedia.Current.TakePhotoAsync(new
Plugin.Media.Abstractions.StoreCameraMediaOptions
{
Directory = "Sample",
Name = "test.jpg",
SaveToAlbum = saveToGallery.IsToggled
});
if (file == null)
return;
https://riptutorial.com/fr/home 198
pickPhoto.Clicked += async (sender, args) =>
{
if (!CrossMedia.Current.IsPickPhotoSupported)
{
await DisplayAlert("Photos Not Supported", ":( Permission not granted to
photos.", "OK");
return;
}
try
{
Stream stream = null;
var file = await CrossMedia.Current.PickPhotoAsync().ConfigureAwait(true);
if (file == null)
return;
stream = file.GetStream();
file.Dispose();
}
catch //(Exception ex)
{
// Xamarin.Insights.Report(ex);
// await DisplayAlert("Uh oh", "Something went wrong, but don't worry we
captured it in Xamarin Insights! Thanks.", "OK");
}
};
try
{
var file = await CrossMedia.Current.TakeVideoAsync(new
Plugin.Media.Abstractions.StoreVideoOptions
{
Name = "video.mp4",
Directory = "DefaultVideos",
SaveToAlbum = saveToGallery.IsToggled
});
if (file == null)
return;
file.Dispose();
}
catch //(Exception ex)
{
https://riptutorial.com/fr/home 199
// Xamarin.Insights.Report(ex);
// await DisplayAlert("Uh oh", "Something went wrong, but don't worry we
captured it in Xamarin Insights! Thanks.", "OK");
}
};
if (file == null)
return;
}
catch //(Exception ex)
{
//Xamarin.Insights.Report(ex);
//await DisplayAlert("Uh oh", "Something went wrong, but don't worry we
captured it in Xamarin Insights! Thanks.", "OK");
}
};
}
}
}
Plugin de messagerie
Plug-in de messagerie pour Xamarin et Windows pour passer un appel, envoyer un SMS ou
envoyer un courrier électronique en utilisant les applications de messagerie par défaut sur les
différentes plates-formes mobiles.
XAML
</StackLayout>
Code
https://riptutorial.com/fr/home 200
namespace PluginDemo
{
public partial class MessagingPage : ContentPage
{
public MessagingPage()
{
InitializeComponent();
buttonCall.Clicked += async (sender, e) =>
{
try
{
// Make Phone Call
var phoneCallTask = MessagingPlugin.PhoneDialer;
if (phoneCallTask.CanMakePhoneCall)
phoneCallTask.MakePhoneCall(phone.Text);
else
await DisplayAlert("Error", "This device can't place calls", "OK");
}
catch
{
// await DisplayAlert("Error", "Unable to perform action", "OK");
}
};
https://riptutorial.com/fr/home 201
Plugin d'autorisations
Vérifiez si vos utilisateurs ont accordé ou refusé des autorisations pour les groupes de
permissions communs sur iOS et Android.
De plus, vous pouvez demander des autorisations avec une simple API asynchrone / attendue
multiplate-forme.
XAML
</StackLayout>
Code
bool busy;
async void ButtonPermission_OnClicked(object sender, EventArgs e)
{
if (busy)
return;
busy = true;
((Button)sender).IsEnabled = false;
https://riptutorial.com/fr/home 202
case "Contacts":
status = await
CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Contacts);
break;
case "Microphone":
status = await
CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Microphone);
break;
case "Phone":
status = await
CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Phone);
break;
case "Photos":
status = await
CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Photos);
break;
case "Reminders":
status = await
CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Reminders);
break;
case "Sensors":
status = await
CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Sensors);
break;
case "Sms":
status = await
CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Sms);
break;
case "Storage":
status = await
CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Storage);
break;
}
if (status != PermissionStatus.Granted)
{
switch (((Button)sender).StyleId)
{
case "Calendar":
status = (await
CrossPermissions.Current.RequestPermissionsAsync(Permission.Calendar))[Permission.Calendar];
break;
case "Camera":
status = (await
CrossPermissions.Current.RequestPermissionsAsync(Permission.Camera))[Permission.Camera];
break;
case "Contacts":
status = (await
CrossPermissions.Current.RequestPermissionsAsync(Permission.Contacts))[Permission.Contacts];
break;
case "Microphone":
status = (await
CrossPermissions.Current.RequestPermissionsAsync(Permission.Microphone))[Permission.Microphone];
break;
case "Phone":
status = (await
CrossPermissions.Current.RequestPermissionsAsync(Permission.Phone))[Permission.Phone];
break;
https://riptutorial.com/fr/home 203
case "Photos":
status = (await
CrossPermissions.Current.RequestPermissionsAsync(Permission.Photos))[Permission.Photos];
break;
case "Reminders":
status = (await
CrossPermissions.Current.RequestPermissionsAsync(Permission.Reminders))[Permission.Reminders];
break;
case "Sensors":
status = (await
CrossPermissions.Current.RequestPermissionsAsync(Permission.Sensors))[Permission.Sensors];
break;
case "Sms":
status = (await
CrossPermissions.Current.RequestPermissionsAsync(Permission.Sms))[Permission.Sms];
break;
case "Storage":
status = (await
CrossPermissions.Current.RequestPermissionsAsync(Permission.Storage))[Permission.Storage];
break;
}
busy = false;
((Button)sender).IsEnabled = true;
}
busy = true;
((Button)sender).IsEnabled = false;
try
{
var status = await
CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
if (status != PermissionStatus.Granted)
{
if (await
CrossPermissions.Current.ShouldShowRequestPermissionRationaleAsync(Permission.Location))
{
await DisplayAlert("Need location", "Gunna need that location", "OK");
}
if (status == PermissionStatus.Granted)
{
var results = await CrossGeolocator.Current.GetPositionAsync(10000);
LabelGeolocation.Text = "Lat: " + results.Latitude + " Long: " +
results.Longitude;
}
https://riptutorial.com/fr/home 204
else if (status != PermissionStatus.Unknown)
{
await DisplayAlert("Location Denied", "Can not continue, try again.",
"OK");
}
}
catch (Exception ex)
{
((Button)sender).IsEnabled = true;
busy = false;
}
https://riptutorial.com/fr/home 205
Crédits
S.
Chapitres Contributeurs
No
Accès aux
fonctionnalités
2 Gerald Versluis, hankide, hvaughan3, Sergey Metlov
natives avec
DependencyService
Ajustements visuels
3 spécifiques à la Alois, GalaxiaGuy, Paul
plate-forme
AppSettings Reader
5 Ben Ishiyama-Levy, GvSharma
dans Xamarin.Forms
Base de données
6 SQL et API dans les RIYAZ
formulaires Xamarin.
CarouselView -
7 dpserge
Version préliminaire
Cellules
8 Eng Soon Cheah
Xamarin.Forms
Comportement
9 spécifique à la plate- Ege Aydın
forme
Contact Picker -
10 Formulaires Xamarin Pucho Eric
(Android et iOS)
Création de
11 contrôles hvaughan3, spaceplane, Yehor Hromadskyi
personnalisés
Cycle de vie de
12 l'application Zverev Eugene
Xamarin.Forms
https://riptutorial.com/fr/home 206
générique? Plate-
forme dépendante!
Déclencheurs et
13 hamalaiv, hvaughan3
comportements
Gestion des
18 Yehor Hromadskyi
exceptions
Mise en forme de
22 Eng Soon Cheah, Gerald Versluis, Lucas Moura Veloso
Xamarin
Mise en page
23 Ege Aydın
relative au Xamarin
Polices
28 personnalisées dans Roma Rudyak
les styles
31 Services de RIYAZ
https://riptutorial.com/fr/home 207
dépendance
Utilisation de
36 cvanbeek
ListViews
https://riptutorial.com/fr/home 208