19
.NET Compact Framework, Tébourbi Riadh, SUP’COM Développement d’applications mobiles sur .net Compact Framework Tébourbi Riadh SUP’COM 2005 Partie 2 XML et données locales Mise à jour Décembre 2006

NET DotNet CF - 2

Embed Size (px)

DESCRIPTION

.NET

Citation preview

Page 1: NET DotNet CF - 2

.NET Compact Framework, Tébourbi Riadh, SUP’COM

Développement d’applications mobiles sur .net Compact Framework

Tébourbi Riadh

SUP’COM

2005

Partie 2

XML et données localesMise à jour Décembre 2006

Page 2: NET DotNet CF - 2

.NET Compact Framework, Tébourbi Riadh, SUP’COM

2

I.Introduction

Bien que les périphériques mobiles soient intégrés au système d'information de l'entreprise et connectées physiquement à son réseau, il est nécessaire de stocker des informations en local. En effet, il est rare de disposer de périphériques mobiles connectés en permanence. Il faut donc pouvoir gérer les scénarii « Online / Offline » et les opérations de synchronisation des données. Pour cela, il est donc nécessaire de stocker des données en local. Une des méthodes que propose le Compact Framework .Net pour stocker et/ou de manipuler des données est d’utiliser des fichiers XML.

II. Le langage XML

XML (Extensible Markup Language, ou Langage Extensible de Balisage) est, comme HTML (Hypertext Markup Language), est un langage de balisage (markup), c'est-à-dire un langage qui présente de l'information encadrée par des balises. Mais contrairement à HTML, qui présente un jeu limité de balises orientées présentation (titre, paragraphe, image, lien hypertexte, etc.), XML est un métalangage, qui va permettre d'inventer à volonté de nouvelles balises pour isoler toutes les informations élémentaires (titre d'ouvrage, prix d'article, numéro de sécurité sociale, référence de pièce…), ou agrégats d'informations élémentaires, que peut contenir une page Web. XML est utilisé aujourd’hui comme un langage standard pour stocker et échanger des données.

III. L’application Pays

Pour illustrer comment utiliser XML pour stocker des données en local, nous allons réaliser une application utilisant des données sur les pays du monde. Une table pays.xml contient des informations concernant chaque pays du monde. Voici un aperçu de ce fichier :

<pays><NOM>Tunisia</NOM><POPULATION>8620181</POPULATION><DEVISE>Dinar</DEVISE><SURFACE>155402</SURFACE></pays><pays><NOM>Algeria</NOM><POPULATION>27459230</POPULATION><DEVISE>Dinar</DEVISE><SURFACE>2320972</SURFACE></pays><pays>…

Page 3: NET DotNet CF - 2

.NET Compact Framework, Tébourbi Riadh, SUP’COM

3

Cette table possède donc 4 attributs : « NOM », « POPULATION », « DEVISE » et « SURFACE ».En plus de ces informations alphanumériques, nous disposons aussi de fichiers images représentant les drapeaux de chaque pays.Nous allons créer une application qui affiche pour chaque pays ses informations et son drapeau. D’une façon plus précise voici les fonctionnalités de l’application :

1. Lecture des données des pays stockées dans un fichier XML2. Offrir à l’utilisateur la possibilité de d’entrer un nom de pays, l’application recherche alors ce pays

dans la base et si ce pays existe elle affiche ses informations et son drapeau.3. Offrir à l’utilisateur la possibilité de rechercher un pays par mot clé. Les noms des pays trouvés son

alors affichés dans une liste et l’utilisateur, en sélectionnant un pays, il peut afficher ses informations complètes.

Phase 1

Créer une nouvelle solution mobile (VB) appelée « dbpays_vb » sous Visual Studio 2005. Dans « l’Explorateur de solution » ajouter le fichier fourni « pays.xml » : Click droit sur le nom du projet « dbpays_vb » puis « AddExisting item », spécifier alors où se trouve le fichier pays.xml. Ce fichier sera ajouté à la liste des fichiers du projet et sera copié dans le répertoire racine de la solution.

Pour que le fichier « pays.xml » soit copié sur le PocketPC lors du déploiement de la solution (en même temps que l’exécutable) il faut modifier sa propriété « Copy to output directory » et la mettre à « Copy if newer ».

Page 4: NET DotNet CF - 2

.NET Compact Framework, Tébourbi Riadh, SUP’COM

4

De même créez un répertoire flags dans l’explorateur de solution (Add New Folder) et ajoutez-y les fichiers images (drapeaux des pays).

Ajouter un contrôle « TabControl » sur la « Form ». Ce contrôle permet d’avoir plusieurs fenêtres (« Tabpages ») accessibles par onglet.

Vous pouvez accéder aux propriétés du « TabContrôle » en utilisant sa propriété « TabPages ». Vous pouvez alors personnaliser les différentes pages (« TabPages ») de ce « TabControle» :

Placer les contrôles ici

Les onglets permettant d’accéder aux autres pages

Page 5: NET DotNet CF - 2

.NET Compact Framework, Tébourbi Riadh, SUP’COM

5

Pour notre application nous avons besoins de deux «TabPages » (TabPage1 et TabPage2) pour placer nos contrôles et créer l’interface graphique.

- Dans la première page « TabPage 1 » :

Sur cette page nous allons offrir la fonctionnalité 1 de l’application (afficher les informations d’un pays donné). Pour cela, mettez l’attribut « Text » de « TabPage1 » à « Infos » et ajouter les contrôles suivants :

Page 6: NET DotNet CF - 2

.NET Compact Framework, Tébourbi Riadh, SUP’COM

6

L’utilisateur entre un nom de pays dans la zone TextBox « Npays », clique sur le bouton « Info » , les information du pays seront affichées sur les contrôles Label : « Pop », « Dev » et « Surf ». Le drapeau du pays (image) sera affiché sur la PictureBox « Flag ».

TextBox« Npays »

Label

Label

Label

Bouton« Info »

Label« Pop »

Label« Dev »

Label

Label« Surf »

PictureBox« Flag »

TabControl

Page 7: NET DotNet CF - 2

.NET Compact Framework, Tébourbi Riadh, SUP’COM

7

- Dans la deuxième page « TabPage 2 » :

Sur cette page nous allons offrir la fonctionnalité 2 de l’application (rechercher des pays par mot clé et afficher les informations d’un pays sélectionné). Pour cela, mettez l’attribut « Text » de « TabPage2 » à « Rechercher » et ajouter les contrôles suivants :

Page 8: NET DotNet CF - 2

.NET Compact Framework, Tébourbi Riadh, SUP’COM

8

L’utilisateur entre le critère de recherche dans la zone de texte « « Crit », il clique sur le bouton « Rech », les résultats de recherche (noms de pays) seront affichés dans la ListBox « Result ». En sélectionnant un pays de la liste et en cliquant sur le bouton « Ainfo », les informations de ce pays seront affichés sur la page « Infos » du TabControl.

Bouton« Rech »

Bouton« Ainfo »

ListBox« Result »

Label

TextBox« Crit »

Page 9: NET DotNet CF - 2

.NET Compact Framework, Tébourbi Riadh, SUP’COM

9

L’interface graphique (IHM) étant prête, il temps maintenant de passer à l’implémentation des différentes fonctionnalités.

Phase 2

1) Fonctionnalité 1 : Lire les données du fichier XML utilisation des DataSet

Comme nous l’avons dis dans l’introduction, le Compact Framework .Net permet de stocker et/ou de manipuler des données stockées dans des fichiers XML en utilisant des DataSet.Il est possible d'avoir « une base de données en mémoire » et d'y effectuer tout type d'opérations (recherche, mise à jours, etc). Cela est possible grâce à l'objet « DataSet » qui permet de manipuler des tables « DataTable » constituées de DataRows (enregistrements) et de DataColumns (champs), auxquels on peut attribuer différentes contraintes. Nous allons donc voir comment utiliser ces DataSet afin de consulter et de manipuler des données des pays stockées dans le fichier pays.xml.

La création de DataSet se fait très simplement, il suffit de lui attribuer un ensemble de DataTable et d'ajouter les colonnes à ces DataTable pour construire la structure de la base que l'on souhaite manipuler. Dans notre cas, nous allons créer un DataSet « dbpays » contenant une table DataTable « pays » puis lui ajouter quelques champs:

pays (NOM, POPULATION, DEVISE, SURFACE)

Le champ NOM est une clé primaire.

Page 10: NET DotNet CF - 2

.NET Compact Framework, Tébourbi Riadh, SUP’COM

10

Nous allons créer alors deux variables myDs (DataSet) et myDt (DataTable) :

Dim myDs As New DataSet("dbpays")Dim myDt As DataTable = myDs.Tables.Add("pays")

Pour ajouter les différentes colonnes (DataColumn ) à la dataTable Mydt :

myDt.Columns.Add("NOM", System.Type.GetType("System.String")) myDt.Columns.Add("POPULATION", System.Type.GetType("System.String")) myDt.Columns.Add("DEVISE", System.Type.GetType("System.String"))

myDt.Columns.Add("SURFACE", System.Type.GetType("System.String"))

Il faut ensuite utiliser la propriété PrimaryKey de myDt (myDt.PrimaryKey) pour indiquer quelles colonnes sont des clés primaires :

Dim PrimaryKeyColumns(0) As DataColumn ‘Tableau de colonnesPrimaryKeyColumns(0) = myDt.Columns("NOM") ‘premier élément du tableau contient la

colonne NOMmyDt.PrimaryKey = PrimaryKeyColumns ‘attribution de la propriété PrimaryKey

Notons que l’instruction myDt.Columns("NOM") permet d’accéder à la colonne NOM de la DataTable.

Pour remplir notre DataSet avec le contenu d’un fichier XML il faut utiliser l’instruction ReadXml(nom_du_fichier_xml) passée au DataSet.

Notre fichier XML pays.xml se trouvera normalement (après déploiement de la solution sur le PocketPC) dans le répertoire racine de l’application. Pour accéder à ce répertoire nous allons utiliser l’instruction :

appath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)

Le répertoire racine de l’application a été sauvegardé dans une variable « appath ».Il suffit maintenant de spécifier le chemin complet du fichier pays.xml pour lire les données à l’aide du DataSet et de l’instruction ReadXml:

myDs.ReadXml(String.Concat(appath, "\pays.xml"))

Notons que String.Concat permet de concaténer plusieurs chaines de caractères (comme l’opérateur +).

Remarque :

Il faut rajouter les références suivante au projet afin de pouvoir utiliser les classe liées aux traitementsdes fichiers XML et ayx DataSet (Solution Explorer, nom du projet, click droit Add Reference):

Page 11: NET DotNet CF - 2

.NET Compact Framework, Tébourbi Riadh, SUP’COM

11

Ensuite il faut importer ces références avant de pouvoir les utiliser dans Form1 :Imports System.DataImports System.Data.SqlClientImports System.IO

Pour résumer :

Nous allons créer deux variables attributs à notre classe Form1 et nous allons effectuer les opérationsd’initialisation dans la méthode Form_Load (la première méthode exécutée au lancement de l’application) :

Imports System.DataImports System.Data.SqlClientImports System.IO

Public Class Form1

Dim myDs As New DataSet("dbpays") Dim myDt As DataTable = myDs.Tables.Add("pays")

Public appath As String

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) HandlesMyBase.Load

'init datatable myDt.Columns.Add("NOM", System.Type.GetType("System.String")) myDt.Columns.Add("POPULATION", System.Type.GetType("System.String")) myDt.Columns.Add("DEVISE", System.Type.GetType("System.String")) myDt.Columns.Add("SURFACE", System.Type.GetType("System.String"))

Page 12: NET DotNet CF - 2

.NET Compact Framework, Tébourbi Riadh, SUP’COM

12

' Make the NOM column the primary key column. Dim PrimaryKeyColumns(0) As DataColumn PrimaryKeyColumns(0) = myDt.Columns("NOM") myDt.PrimaryKey = PrimaryKeyColumns

'Init path variable appath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)

'fill datatable with XML file content myDt.Clear() myDs.ReadXml(String.Concat(appath, "\pays.xml"))

End Sub

2) Créer la classe pays :

Dans notre application nous avons à manipuler des objets pays avec leurs attributs. Il serait judicieux de créer une classe pays (démarche OO).Pour créer une nouvelle classe, faites un click droit sur le nom du projet « dbpays_vb » puis « AddNew item ». Choisissez alors « Class » comme item à insérer et précisez le nom de la classe : pays.

Ouvrez le fichier pays.vb. Notons que la déclaration d’une classe commence par :

Public Class nom_de_la_classe

Et se termine par :

End Class

Page 13: NET DotNet CF - 2

.NET Compact Framework, Tébourbi Riadh, SUP’COM

13

Un pays est définit par ses attributs NOM, POPULATION, DEVISE, SURFACE et DRAPEAU. Il faut alors déclarer ces attributs dans la classe pays :

Imports Microsoft.VisualBasic

Page 14: NET DotNet CF - 2

.NET Compact Framework, Tébourbi Riadh, SUP’COM

14

Imports System.DrawingImports System.Drawing.ImagingImports System.IO

Public Class pays Private Nom As String Private Population As Integer Private Devise As String Private Surface As Integer

Private Drapeau As Byte()….

Notons que Drapeau est déclaré comme un tableau de byte (c’est une image stockée dans un tableau de byte).

Il est possible de rajouter à la classe pays des « getter » et des « setter », ce sont des méthodes qui permettent d’accéder à ses différents attributs. En VB .Net (et en C# aussi) ces méthodes s’appellent des « Properties ». Par exemple, nous allons rajouter la propriété « pNom » qui permettra d’accéder à la propriété NOM de la classe :

Public Property pNom() As String Get Return Nom End Get Set(ByVal value As String) Nom = value End Set

End Property

Par la suite, pour un objet « unpays » de la classe « pays », nous pouvons accéder à son attribut NOM par :

A = unpays.pName ‘En lectureunpays.pName = « Tunisia » ‘En ecriture

De même nous allons rajouter des méthodes pour accéder aux autres attributs de la classe pays à savoir :

Public Property pDevise() As String Get Return Devise End Get Set(ByVal value As String) Devise = value End Set End Property

Public Property pPopulation() As Integer Get Return Population End Get Set(ByVal value As Integer) Population = value End Set

Page 15: NET DotNet CF - 2

.NET Compact Framework, Tébourbi Riadh, SUP’COM

15

End Property

Public Property pSurface() As Integer Get Return Surface End Get Set(ByVal value As Integer) Surface = value End Set End Property

Public Property pDrapeau() As Byte() Get Return Drapeau End Get

Set(ByVal value As Byte()) Drapeau = value End Set

End Property

En ce qui concerne les constructeurs de la classe pays nous allons en définir deux : un sans paramètres (par défaut) et un avec 4 paramètres.

Pour le constructeur sans paramètres il s’agit de construire un pays par défaut :

Public Sub New() ' ----- Default constructor. Nom = "?" Population = 0 Devise = "?" Surface = 0 setDrapeau()

End Sub

Pour le constructeur ayant 4 paramètres il s’agit de passer en argument des valeurs String pour les 4 premiers attributs :

Public Sub New(ByVal n As String, ByVal pop As Integer, ByVal dev As String, ByValsurf As Integer)

' ----- Default constructor. Nom = n Population = pop Devise = dev Surface = surf setDrapeau() End Sub

Notons que pour les deux constructeurs, l’attribut Drapeau de la classe sera définit dans une méthode setDrapeau(). Cette méthode définira automatiquement le drapeau du pays à partir de son nom. En effet, par convention, le nom du fichier image est le même que le nom du pays : par exemple pour NOM= « Tunisia » le drapeau correspondant est : « /appath/flags/tunisia.png », pour un pays inconnu (NOM= « ? » , définit par le constructeur vide) le fichier drapeau est « /appath/flags/unknown.png »,:

Page 16: NET DotNet CF - 2

.NET Compact Framework, Tébourbi Riadh, SUP’COM

16

Private Sub setDrapeau() Dim MyImg As Image

If (Nom <> "?") Then MyImg = New Bitmap(String.Concat(Form1.appath, "\flags\", Nom, ".png")) Else MyImg = New Bitmap(String.Concat(Form1.appath, "\flags\unknown.png")) End If

Dim MemStr As New MemoryStream() MyImg.Save(MemStr, ImageFormat.Png)

Me.pDrapeau = MemStr.GetBuffer() End Sub

Dans cette méthode on commence par lire le fichier image drapeau du pays (selon son Nom) et le stocker dans la variable myImage.Ensuite, cette image est stockée dans un flux de données (MemoryStream) au format Png , puis, on récupère le tableau de byte par la méthode GetBuffer de la classe MemoryStream.

Phase 3

1) Fonctionnalité 2

Quand on clique sur le bouton « Info » l’application va chercher un pays dont le nom est donné par l’utilisateur grâce à la zone de texte « Npays ». Si le pays existe ses information seront affichées si ce pays n’existe pas des informations par défaut seront utilisées. Cette fonctionnalité est implémentée dans une méthode afficheInfos() de la classe Form1 :

Private Sub afficheInfos() Dim objBitmap As Bitmap Dim strmBuffer As MemoryStream

Dim myrow As DataRow = myDt.Rows.Find(Npays.Text) Dim p As pays

If myrow IsNot Nothing Then p = New pays(Npays.Text, Integer.Parse(myrow("POPULATION").ToString), myrow("DEVISE").ToString(), Integer.Parse(myrow("SURFACE").ToString))

Else p = New pays() End If

Pop.Text = p.pPopulation Surf.Text = p.pSurface Dev.Text = p.pDevise.ToString Npays.Text = p.pNom.ToString

strmBuffer = New System.IO.MemoryStream(p.pDrapeau) objBitmap = New Bitmap(strmBuffer) Flag.Image = objBitmap

End Sub

Page 17: NET DotNet CF - 2

.NET Compact Framework, Tébourbi Riadh, SUP’COM

17

Pour chercher dans une table un enregistrement particulier dont la valeur d’une clé primaire est égale à « criteria » il faut utiliser la méthode « find » :

Dim myrow As DataRow = myDt.Rows.Find(criteria)

On récupère ainsi un objet de la classe DataRow (myrow) qui est la ligne recherchée de la table (myrow est vide si pas de résultat trouvé).A partir de cette variable « myrow » nous pouvons ensuite construire un objet p de la classe pays (si myrow est null un objet par défaut est construit utilisation du constructeur par défaut).Les informations de ce pays p construit sont ensuite affichées sur la « TabPage1 ».

L’image du drapeau du pays est construite à partir de p.pDrapeau (tableau de byte) en réalisant l’opération inverse : créer une image à partir d’un tableau de byte. Pour cela un objet MemoryStream (strmBuffer) est encore utilisé, il est construit à partir du tableau de byte : p.pDrapeau :

strmBuffer = New System.IO.MemoryStream(p.pDrapeau)

Un objet Bitmap (objBitmap) est ensuite construit à partir du MemoryStream et sa valeur est enfin attribuée à la propriété Image de la PictureBox « Flag » :

objBitmap = New Bitmap(strmBuffer) Flag.Image = objBitmap

Cette méthode, afficheInfos, est appelée dans l’événement Click sur le bouton « Info » de telle manière qu’elle est exécutée quand on clique sur ce bouton :

Private Sub Info_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Info.Click

afficheInfos()

End Sub

2) Fonctionnalité 3 : Rechercher un pays

Quand l’utilisateur entre un critère de recherche dans la zone texte « Crit » et clique sur le bouton « Rech » l’application recherche les pays contenant la chaine de caractères définie dans « Crit » et affiche leurs noms dans la liste « Result ».

La méthode « select » de la classe DataSet est utilisée pour rechercher des enregistrements particuliers selon un critère (SQL) donné. Le résultat est récupéré dans un tableau de « DataRow » (foundRows) :

Dim expression As String Dim sortOrder As String

expression = "NOM LIKE " & "'%" & Crit.Text & "%'" ' Sort descending by Name column. sortOrder = "NOM ASC"

' Use the Select method to find all rows matching the criteria.Dim foundRows As DataRow() = myDt.Select(expression, sortOrder, DataViewRowState.Added)

Les lignes trouvées de la table sont ensuite utilisées pour remplir la liste par les noms des pays trouvés :

Page 18: NET DotNet CF - 2

.NET Compact Framework, Tébourbi Riadh, SUP’COM

18

'fill the list box with found results Result.Items.Clear() If foundRows.Length <= 0 Then Exit Sub End If

Dim row As DataRow For Each row In foundRows Result.Items.Add(row("NOM")) Next row

Pour résumer

Private Sub Rech_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Rech.Click

Dim expression As String Dim sortOrder As String

expression = "NOM LIKE " & "'%" & Crit.Text & "%'" ' Sort descending by Name column. sortOrder = "NOM ASC"

' Use the Select method to find all rows matching the criteria. Dim foundRows As DataRow() = myDt.Select(expression, sortOrder, DataViewRowState.Added)

'fill the list box with found results Result.Items.Clear() If foundRows.Length <= 0 Then Exit Sub End If

Dim row As DataRow For Each row In foundRows Result.Items.Add(row("NOM")) Next row

End Sub

En sélectionnant un pays de la liste et en cliquant sur le bouton « Ainfo » , les informations du pays seront affichées sur la « TabPage1 » :

Private Sub Ainfo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Ainfo.Click

If (Result.Items.Count > 0) Then Npays.Text = Result.SelectedItem.ToString afficheInfos() TabPage1.BringToFront() TabPage2.SendToBack() End If End Sub

Une fois que la zone de texte « Npays » est initialisée par le nom du pays sélectionné, la méthode afficheInfos() est appelée.

Page 19: NET DotNet CF - 2

.NET Compact Framework, Tébourbi Riadh, SUP’COM

19

Notons que pour accéder à l’élément sélectionné de la liste (ListBox) on utilise sa propriété SelectedItem.