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




Développement d’applications mobiles sur
       .net Compact Framework...
.NET Compact Framework, Tébourbi Riadh, SUP’COM




       I.Introduction

Bien que les périphériques mobiles soient intég...
.NET Compact Framework, Tébourbi Riadh, SUP’COM

Cette table possède donc 4 attributs : « NOM », « POPULATION », « DEVISE ...
.NET Compact Framework, Tébourbi Riadh, SUP’COM


De même créez un répertoire flags dans l’explorateur de solution (Add N...
.NET Compact Framework, Tébourbi Riadh, SUP’COM




Pour notre application nous avons besoins de deux «TabPages » (TabPage...
.NET Compact Framework, Tébourbi Riadh, SUP’COM




         TextBox
         « Npays »                                   ...
.NET Compact Framework, Tébourbi Riadh, SUP’COM




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

Sur cette page nous allons ...
.NET Compact Framework, Tébourbi Riadh, SUP’COM




            Label


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




L’interface graphique (IHM) étant prête, il temps maintenant de passer...
.NET Compact Framework, Tébourbi Riadh, SUP’COM



Nous allons créer alors deux variables myDs (DataSet) et myDt (DataTabl...
.NET Compact Framework, Tébourbi Riadh, SUP’COM




Ensuite il faut importer ces références avant de pouvoir les utiliser ...
.NET Compact Framework, Tébourbi Riadh, SUP’COM

      ' Make the NOM column the primary key column.
      Dim PrimaryKeyC...
.NET Compact Framework, Tébourbi Riadh, SUP’COM




Un pays est définit par ses attributs NOM, POPULATION, DEVISE, SURFACE...
.NET Compact Framework, Tébourbi Riadh, SUP’COM
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.IO

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


Public Property pSurface() As Integer
     Get
       ...
.NET Compact Framework, Tébourbi Riadh, SUP’COM


Private Sub setDrapeau()
     Dim MyImg As Image

      If (Nom <> quot;...
.NET Compact Framework, Tébourbi Riadh, SUP’COM

Pour chercher dans une table un enregistrement particulier dont la valeur...
.NET Compact Framework, Tébourbi Riadh, SUP’COM


      'fill the list box with found results
      Result.Items.Clear()
 ...
.NET Compact Framework, Tébourbi Riadh, SUP’COM


Notons que pour accéder à l’élément sélectionné de la liste (ListBox) on...
Upcoming SlideShare
Loading in...5
×

.NET DotNet CF - 2

966

Published on

.NET

Published in: Technology, News & Politics
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
966
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
37
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of ".NET DotNet CF - 2"

  1. 1. .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
  2. 2. .NET Compact Framework, Tébourbi Riadh, SUP’COM 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> … 2
  3. 3. .NET Compact Framework, Tébourbi Riadh, SUP’COM 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 XML 2. 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 « AddExisting 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 ». 3
  4. 4. .NET Compact Framework, Tébourbi Riadh, SUP’COM 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. Placer les contrôles ici Les onglets permettant d’accéder aux autres pages 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» : 4
  5. 5. .NET Compact Framework, Tébourbi Riadh, SUP’COM 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 : 5
  6. 6. .NET Compact Framework, Tébourbi Riadh, SUP’COM TextBox « Npays » Label Bouton « Info » Label Label Label « Pop » Label Label « Dev » PictureBox « Flag » Label « Surf » TabControl 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 ». 6
  7. 7. .NET Compact Framework, Tébourbi Riadh, SUP’COM - 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 : 7
  8. 8. .NET Compact Framework, Tébourbi Riadh, SUP’COM Label Bouton « Rech » TextBox « Crit » ListBox « Result » Bouton « Ainfo » 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. 8
  9. 9. .NET Compact Framework, Tébourbi Riadh, SUP’COM 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. 9
  10. 10. .NET Compact Framework, Tébourbi Riadh, SUP’COM Nous allons créer alors deux variables myDs (DataSet) et myDt (DataTable) : Dim myDs As New DataSet(quot;dbpaysquot;) Dim myDt As DataTable = myDs.Tables.Add(quot;paysquot;) Pour ajouter les différentes colonnes (DataColumn ) à la dataTable Mydt : myDt.Columns.Add(quot;NOMquot;, System.Type.GetType(quot;System.Stringquot;)) myDt.Columns.Add(quot;POPULATIONquot;, System.Type.GetType(quot;System.Stringquot;)) myDt.Columns.Add(quot;DEVISEquot;, System.Type.GetType(quot;System.Stringquot;)) myDt.Columns.Add(quot;SURFACEquot;, System.Type.GetType(quot;System.Stringquot;)) 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 colonnes PrimaryKeyColumns(0) = myDt.Columns(quot;NOMquot;) ‘premier élément du tableau contient la colonne NOM myDt.PrimaryKey = PrimaryKeyColumns ‘attribution de la propriété PrimaryKey Notons que l’instruction myDt.Columns(quot;NOMquot;) 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().G etName().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, quot;pays.xmlquot;)) 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 traitements des fichiers XML et ayx DataSet (Solution Explorer, nom du projet, click droit  Add Reference): 10
  11. 11. .NET Compact Framework, Tébourbi Riadh, SUP’COM Ensuite il faut importer ces références avant de pouvoir les utiliser dans Form1 : Imports System.Data Imports System.Data.SqlClient Imports System.IO Pour résumer : Nous allons créer deux variables attributs à notre classe Form1 et nous allons effectuer les opérations d’initialisation dans la méthode Form_Load (la première méthode exécutée au lancement de l’application) : Imports System.Data Imports System.Data.SqlClient Imports System.IO Public Class Form1 Dim myDs As New DataSet(quot;dbpaysquot;) Dim myDt As DataTable = myDs.Tables.Add(quot;paysquot;) Public appath As String Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load 'init datatable myDt.Columns.Add(quot;NOMquot;, System.Type.GetType(quot;System.Stringquot;)) myDt.Columns.Add(quot;POPULATIONquot;, System.Type.GetType(quot;System.Stringquot;)) myDt.Columns.Add(quot;DEVISEquot;, System.Type.GetType(quot;System.Stringquot;)) myDt.Columns.Add(quot;SURFACEquot;, System.Type.GetType(quot;System.Stringquot;)) 11
  12. 12. .NET Compact Framework, Tébourbi Riadh, SUP’COM ' Make the NOM column the primary key column. Dim PrimaryKeyColumns(0) As DataColumn PrimaryKeyColumns(0) = myDt.Columns(quot;NOMquot;) 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, quot;pays.xmlquot;)) 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 « AddNew 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 12
  13. 13. .NET Compact Framework, Tébourbi Riadh, SUP’COM 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 13
  14. 14. .NET Compact Framework, Tébourbi Riadh, SUP’COM Imports System.Drawing Imports System.Drawing.Imaging Imports 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 lecture unpays.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 14
  15. 15. .NET Compact Framework, Tébourbi Riadh, SUP’COM 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 = quot;?quot; Population = 0 Devise = quot;?quot; 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, ByVal surf 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 »,: 15
  16. 16. .NET Compact Framework, Tébourbi Riadh, SUP’COM Private Sub setDrapeau() Dim MyImg As Image If (Nom <> quot;?quot;) Then MyImg = New Bitmap(String.Concat(Form1.appath, quot;flagsquot;, Nom, quot;.pngquot;)) Else MyImg = New Bitmap(String.Concat(Form1.appath, quot;flagsunknown.pngquot;)) 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(quot;POPULATIONquot;).ToString), myrow(quot;DEVISEquot;).ToString(), Integer.Parse(myrow(quot;SURFACEquot;).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 16
  17. 17. .NET Compact Framework, Tébourbi Riadh, SUP’COM 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 = quot;NOM LIKE quot; & quot;'%quot; & Crit.Text & quot;%'quot; ' Sort descending by Name column. sortOrder = quot;NOM ASCquot; ' 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 : 17
  18. 18. .NET Compact Framework, Tébourbi Riadh, SUP’COM '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(quot;NOMquot;)) 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 = quot;NOM LIKE quot; & quot;'%quot; & Crit.Text & quot;%'quot; ' Sort descending by Name column. sortOrder = quot;NOM ASCquot; ' 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(quot;NOMquot;)) 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. 18
  19. 19. .NET Compact Framework, Tébourbi Riadh, SUP’COM Notons que pour accéder à l’élément sélectionné de la liste (ListBox) on utilise sa propriété SelectedItem. 19

×