# Complément Formation Xamarin

## Alexandre Journaux

► To cite this version:

| Alexandre Journaux. Complément Formation Xamarin. Licence. France. 2021. hal-03187560

HAL Id: hal-03187560

https://hal.science/hal-03187560v1

Submitted on 1 Apr 2021

HAL is a multi-disciplinary open access
archive for the deposit and dissemination of sci-
entific research documents, whether they are pub-
lished or not. The documents may come from
teaching and research institutions in France or
abroad, or from public or private research centers.

L'archive ouverte pluridisciplinaire HAL, est
destinée au dépôt et à la diffusion de documents
scientifiques de niveau recherche, publiés ou non,
émanant des établissements d'enseignement et de
recherche français ou étrangers, des laboratoires
publics ou privés.

<figure><img src="image_1.png" /></figure>

Distributed under a Creative Commons CC BY 4.0 - Attribution - International License
<figure><img src="image_2.png" /></figure>

# Complément Formation Xamarin

En partant d'un exemple de programme à réaliser

Liste d'élevages

<figure><img src="image_3.png" /></figure>

Numéro animal

OK

Poids animal

Enregistrer

## Objectif du programme :

Enregistrer la pesée d'un animal

## Etapes :

1. Sélectionner un élevage

2. Saisir un numéro animal

3. Valider la saisie (= vérifier qu'il existe dans l'élevage sélectionné)

4. Saisir le poids

5. Enregistrer (simuler l'enregistrement en affichant les infos saisies)

<figure><img src="image_4.png" /></figure>
<figure><img src="image_5.png" /></figure>

# Complément Formation Xamarin

En partant d'un exemple de programme à réaliser

<figure><img src="image_6.png" /></figure>

## Objectif de la programmation :

Utiliser les pattern MVVM et DAO

<figure><img src="image_7.png" /></figure>
<figure><img src="image_8.png" /></figure>

# Complément Formation Xamarin

En partant d'un exemple de programme à réaliser

Liste d'élevages ▼

Numéro animal OK

Poids animal

Enregistrer

## Objectif de la programmation :

Utiliser les pattern MVVM et DAO

<figure><img src="image_9.png" /></figure>
<figure><img src="image_10.png" /></figure>

# Complément Formation Xamarin

## Modèle de données

### Model

Liste d'élevages

<figure><img src="image_11.png" /></figure>

Numéro animal

OK

Poids animal

Enregistrer

## Diagramme de classes :

<figure><img src="image_12.png" /></figure>

Donc 3 classes à écrire dans le dossier Model
<figure><img src="image_13.png" /></figure>

# Complément Formation Xamarin

## Accès aux données

DAO

Liste d'élevages

<figure><img src="image_14.png" /></figure>

Numéro animal

OK

Poids animal

Enregistrer

## Fonctions dont on a besoin :

- Lister tous les élevages de la base de données

- Lister tous les animaux d'un élevage

- Enregistrer la pesée

- => 3 méthodes à écrire :

- `List<Elevage> getElevages()`

- `List<Animal> getAnimauxByElevage(Elevage el)`

- `void save(Pesee pe)`

- Comme ces 3 méthodes concernent 3 objets différents, il est recommandé de **créer 3 classes dans le dossier DAO** :

- `ElevageDAO`

- `AnimalDAO`

- `PeseeDAO`
<figure><img src="image_15.png" /></figure>

# Complément Formation Xamarin

## Construction de l'IHM

View

Liste d'élevages

<figure><img src="image_16.png" /></figure>

Numéro animal

OK

Résultat validation numéro

Poids animal

Enregistrer

## Composition de l'écran :

- Une grille (2 colonnes, 5 lignes) : <Grid>

- Une liste déroulante : <Picker>

- Deux champs de saisie : <Entry>

- Deux boutons : <Button>

- Un texte d'affichage : <Label>

Donc 1 vue à écrire dans le dossier View : PeseeAnimalView
<figure><img src="image_17.png" /></figure>

# Complément Formation Xamarin

## Construction de l'IHM

View

Liste d'élevages

<figure><img src="image_18.png" /></figure>

Numéro animal

OK

Résultat validation numéro

Poids animal

Enregistrer

### La grille :

- `<Grid ColumnDefinitions="75*,25*" RowDefinitions="auto,auto,auto,auto,auto">`

### La liste déroulante :

- `<Picker GridRow="0" GridColumnSpan="2" Title="Liste des élevages" ItemsSource="{Binding Elevages}" ItemDisplayBinding="{Binding ElevageNom}" SelectedItem="{Binding ElevageSelectionne}"/>`
<figure><img src="image_19.png" /></figure>

# Complément Formation Xamarin

Construction de l'IHM

View

Liste d'élevages

<figure><img src="image_20.png" /></figure>

Numéro animal

OK

Résultat validation numéro

Poids animal

Enregistrer

## Les 2 champs de saisie :

<Entry Grid.Row="1" Grid.column="0" Placeholder="Numéro animal" Text="{Binding AnimalNumero}" Keyboard="Numeric"/>

<Entry GridRow="3" GridColumn="0" Placeholder="Poids" Text="{Binding AnimalPoids}" Keyboard="Numeric"/>
<figure><img src="image_21.png" /></figure>

# Complément Formation Xamarin

## Construction de l'IHM

View

Liste d'élevages

<figure><img src="image_22.png" /></figure>

Numéro animal

OK

Résultat validation numéro

Poids animal

Enregistrer

### Les 2 boutons :

<Button Grididd Row="1" GridColumn="1" Text="OK" Command="{Binding ValiderNumeroAnimalCommand}"/>

<Button Grididd Row="4" GridColumnSpan="2" Text="Enregistrer" Command="{Binding EnregistrerCommand}"/>

### Le texte :

<Label Grididd Row="2" GridColumnSpan="2" Text="{Binding RetourValidation}"/>
<figure><img src="image_23.png" /></figure>

# Complément Formation Xamarin

Construction de l'IHM

View

Liste d'élevages

<figure><img src="image_24.png" /></figure>

Numéro animal

OK

Résultat validation numéro

Poids animal

Enregistrer

Pour que la vue soit appelée au démarrage de l'application :

Dans le constructeur de la classe App, ajouter l'appel de la vue :

```csharp
public App()
{
    Nuget InitializeComponent();

    MainPage = new PeseeAnimalView();
}
```
<figure><img src="image_25.png" /></figure>

# Complément Formation Xamarin

## Interagir avec la vue

### ViewModel

Liste d'élevages

<figure><img src="image_26.png" /></figure>

Numéro animal

OK

Résultat validation numéro

Poids animal

Enregistrer

**Afin que le binding fonctionne correctement :**

Créer la classe **BaseViewModel** dans le dossier **ViewModel**

```java
public class BaseViewModel : INotify propertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertybirchEventArg (propertyName));
    }
}
```

Cette classe sera héritée par toutes les autres classes ViewModel afin de bénéficier de la méthode OnPropertyChanged
<figure><img src="image_27.png" /></figure>

# Complément Formation Xamarin

## Interagir avec la vue

### ViewModel

Liste d'élevages

<figure><img src="image_28.png" /></figure>

Numéro animal

OK

Résultat validation numéro

Poids animal

Enregistrer

### Afin d'interagir avec la vue PeseeAnimalView :

- Créer la classe PeseeAnimalViewModel dans le dossier ViewModel

public class PeseeAnimalViewModel : BaseViewModel

### Règle : 1 ViewModel pour 1 View

- Instancier cette classe dans le constructeur de la vue :
  (dans le code Behind)

public PeseeAnimalView()
{
    InitializeComponent();
    peseeAnimalViewplatContext = new PeseeAnimalViewModel();
}
<figure><img src="image_29.png" /></figure>

# Complément Formation Xamarin

## Interagir avec la vue

### ViewModel

Liste d'élevages

<figure><img src="image_30.png" /></figure>

Numéro animal

OK

Résultat validation numéro

Poids animal

Enregistrer

## Afficher la liste des élevages dans la liste déroulante :

L'objet Picker de la vue a 3 propriétés en Binding

- `ItemsSource={Binding Elevages}`
  `Elevages` est une `List<Elevage>` qu'il faut alimenter dans le constructeur par l'appel de la méthode `getElevages()` de `ElevageDAO`

- `ItemDisplayBinding={Binding ElevageNom}`
  `ElevageNom` est la propriété de la classe `Elevage` qui sera affichée dans la liste déroulante

- `SelectedItem={Binding ElevageSelectionne}`
  `ElevageSelectionne` est un objet de type `Elevage` qui correspondra à l'élevage sélectionné
<figure><img src="image_31.png" /></figure>

# Complément Formation Xamarin

## Interagir avec la vue

### ViewModel

Liste d'élevages

<figure><img src="image_32.png" /></figure>

Numéro animal

OK

Résultat validation numéro

Poids animal

Enregistrer

## Lier les propriétés Text des 2 champs de saisie :

- `Text="{Binding AnimalNumero}"`

`AnimalNumero` est un string qui sera alimenté par la saisie de l'utilisateur

- `Text="{Binding AnimalPoids}"`

`AnimalPoids` est un int qui sera alimenté par la saisie de l'utilisateur

## Lier la propriété Text du label :

- `Text="{Binding RetourValidation}"`

`RetourValidation` est un string qui sera alimenté par la validation du bouton « OK »
<figure><img src="image_33.png" /></figure>

# Complément Formation Xamarin

## Interagir avec la vue

ViewModel

Liste d'élevages

<figure><img src="image_34.png" /></figure>

Numéro animal

OK

Résultat validation numéro

Poids animal

Enregistrer

## Faire fonctionner le bouton « OK » :

- `Command={Binding ValiderNumeroAnimalCommand}`

`ValiderNumeroAnimalCommand` est un objet de type `ICommand` qui permet de lier le bouton à une action et à une condition d'exécution

- Déclaration :

`public ICommand ValiderNumeroAnimalCommand { get; private set; }`

- Instanciation dans le construteur du ViewModel :

`ValiderNumeroAnimalCommand = new Command(ValiderNumeroAnimal, CanValiderNumeroAnimal);`

- 2 méthodes à écrire :

`private void ValiderNumeroAnimal()`

Permet de vérifier (et afficher) si le numéro saisi correspond bien à un animal de l'élevage sélectionné

`private bool CanValiderNumeroAnimal()`

Retourne vrai si le numéro animal est saisi
<figure><img src="image_35.png" /></figure>

# Complément Formation Xamarin

## Interagir avec la vue

ViewModel

Liste d'élevages

<figure><img src="image_36.png" /></figure>

Numéro animal

OK

Résultat validation numéro

Poids animal

Enregistrer

## Faire fonctionner le bouton « Enregistrer » :

- `Command={Binding EnregistrerCommand}`

`EnregistrerCommand` est un objet de type `ICommand` qui permet de lier le bouton à une action et à une condition d'exécution

- Déclaration :

```csharp
public ICommand EnregistrerCommand { get; private set; }
```

- Instanciation dans le construteur du ViewModel :

`EnregistrerCommand = new Command(EnregistrerPesee, CanValiderNumeroAnimal);`

- 2 méthodes à écrire :

```csharp
private void EnregistrerPesee()
```

Permet d'enregistrer la pesée par l'appel de la méthode save() de PeseeDAO

```csharp
private bool CanValiderNumeroAnimal()
```

Retourne vrai si le numéro animal est saisi
<figure><img src="image_37.png" /></figure>

# Complément Formation Xamarin

## Interagir avec la vue

### ViewModel

Liste d'élevages

<figure><img src="image_38.png" /></figure>

Numéro animal

OK

Résultat validation numéro

Poids animal

Enregistrer

## Et, enfin, pour que tout fonctionne bien :

Comme la condition sur les commandes dépend de la saisie ou non du numéro animal, lancer la méthode ChangeCanExecute() dans le set de AnimalNumero : ((Command)ValiderNumeroAnimalCommand).ChangeCanExecute(); ((Command)EnregistrerCommand).ChangeCanExecute();
<figure><img src="image_39.png" /></figure>

# Complément Formation Xamarin

Pour aller plus loin...

## Changer la couleur d'un label dynamiquement (1/2) :

- Créer la classe `StringToColorConverter` (dans le dossier Converter)

```csharp
public class StringToColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter,CultureInfo culture)
    {
        string valueAsString = value as String;

        if (valueAsString == null) return Color Default;

        if (valueAsString#")) return Color FromHex(valueAsString);

        if (!valueAsString == "") return System.Drawing.Color FromName(valueAsString);

        return Color Default;
    }
}
```

```csharp
public object ConvertBack(object value, Type targetType, object parameter,CultureInfo culture)
{
    return null;
}
}
```
<figure><img src="image_40.png" /></figure>

# Complément Formation Xamarin

Pour aller plus loin...

## Changer la couleur d'un label dynamiquement (2/2) :

- Dans la vue, mettre en place le binding sur `TextColor`

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
    ...
    xmlns:labelTextColorSample="clr-namespace:PetitProgramme.Converter"
    x:Name="peseeAnimalView">

    <ContentPage/resources>
        <ResourceDictionary>
            ...
            <labelTextColorSample:StringToColorConverter x:Key="StringToColorConverter"/>
            ...
        </ResourceDictionary>
    </ContentPage.resources>

    ...
    <Label Gridaktiv="3" GridColumnSpan="2" Text="{Binding RetourValidation}"
           TextColor="{Binding CouleurMessage, Converter={StaticResource StringToColorConverter}}"/>
    ...
```

- Dans le ViewModel, ajouter la propriété CouleurMessage et coder ses mises à jour
<figure><img src="image_41.png" /></figure>

# Complément Formation Xamarin

Pour aller plus loin...

## Ouvrir une page à partir d'une autre page :

<figure><img src="image_42.png" /></figure>

- Dans le constructeur de la classe App, appeler la 1ère page en paramètre de **NavigationPage()** :

```
MainPage = new NavigationPage( new Page1());
```

- Dans le ViewModel coder le changement de page :

```
App.Current.MainPage Navigation.PushAsync(new Page2());
```

```
App.Current.MainPage Navigation.PopAsync();
```
<figure><img src="image_43.png" /></figure>

# Complément Formation Xamarin

Pour aller plus loin...

## Créer un style pour un contrôle :

```xml
<ContentPage Resources>
    <ResourceDictionary>
        ...
        <x:Int16 x:Key="border">3</x:Int16>
        <Style x:Name="myButton" x:Key="myButton" TargetType="Button">
            <Setter Property="BorderWidth" Value="{DynamicResource border}"/>
            <setter Property="CoroerRadius" Value="10"/>
            <setter Property="BackgroundColor" Value="#00A3A6"/>
            <setter Property="Color" Value="#0077A6"/>
            <setter Property="TextColor" Value="White"/>
            <setter Property="Margin" Value="5,0,5,0"/>
        </Style>
        ...
    </ResourceDictionary>
</ContentPage.resources>

...
<Button Gridlez="2" GridColumn="1" Text="OK" Command="{Binding ValiderNumeroAnimalCommand}«
         Style="{StaticResource myButton}"/>
```