jeudi 10 avril 2008

Awake

Awake, O sword
Hit the walls of unbelief
And tear them down
By the Mighty Power
Of the Almighty God

--
Alain Lompo
Excelta - Conseils et services informatiques
MCT
MCSD For Microsoft .Net
MVP Windows Systems Server / Biztalk Server
Certifié ITIL et Microsoft Biztalk Server

lundi 31 mars 2008

Mais qu'est - ce que le .Net Framework



4) Mais qu’est-ce que le .NET Framework ?

L’architecture .NET peut être définie de la façon suivante :

Il s’agit d’un ensemble de Services communs, utilisables depuis plusieurs langages objet. Ces Services s’exécutent sous la forme d’un code intermédiaire indépendant de l’architecture sous-jacente. Ces Services s’exécutent dans un « runtime » (CLR – Common Language Runtime) assurant les fonctions de gestion des ressources et de surveillance du bon fonctionnement des applications.

A la lecture de cette rapide description, on ne peut s’empêcher de faire un parallèle avec Java.

Effectivement, Microsoft ne se cache pas d’avoir puisé de façon tout à fait pragmatique ses inspirations dans technologies existantes, et en particulier dans le monde Java.

Le but premier de .NET est de fournir aux développeurs les moyens de créer des applications interopérables utilisant des "Web Services" depuis tout type de terminal : PC, assistant personnel, téléphone mobile.






Avec la plateforme .NET, Microsoft fournit plusieurs langages ainsi que les compilateurs associés, tels que VB 2005, C# 2.0, ..

D’autres éditeurs, soucieux de profiter de la vague .NET, écrivent des compilateurs pour d’autres langages non supportés par les équipes de Redmond. Nous y retrouverons des langages aussi divers et insolites que Cobol, Eiffel, Python.

Tous ces langages sont compilés sous la forme d’un langage intermédiaire (Initialement appelé MSIL, rebaptisé IL pour Intermediate Language), indépendant du matériel et du système d’exploitation.

Ce langage « IL » : Microsoft Intermediate Language est ensuite exécuté dans un Runtime, la « CLR » (Common Language Runtime) qui remplit sensiblement le même rôle que la JVM dans la plateforme Java.





Le contrôle DomainUpDown

Le contrôle DomainUpDown

Le contrôle DomainUpDown permet d’afficher une liste occupant peu de place: on ne voit qu'une ligne, on se déplace avec les boutons up et down:
On charge la liste avec:
MondomainUpDown.Items.Add("une ligne")
Quand l'utilisateur change de ligne cela déclenche SelectedItemChanged. Le texte sélectionné est dans SelectedItem.
La sub suivante affiche dans une messageBox l'index et le texte sélectionné.
Private Sub MondomainUpDown1_SelectedItemChanged _ (sender As System.Object, e As System.EventArgs)
MessageBox.Show(("Index sélectionné: " & MondomainUpDown1.SelectedIndex.ToString() & _ ControlChars.Cr & "Item sélectionné: " & MondomainUpDown1.SelectedItem.ToString()))
End Sub
Attention la liste contient des objets, il peut être nécessaire lorsqu'on utilise un des items de caster l'objet en string grace à ToString. Il existe aussi un contrôle NumericUpDown

Actionner les événements les plus courants

1.1. Mettre en œuvre des actions sur les évènements les plus courants :

Dans le code, on peut créer soi-même de toutes pièces, des contrôles et leurs évènements.

1.1.1. Créer par code des contrôles


Dans le code d'une procédure, il est possible de créer de toute pièce un contrôle, mais attention, il faut tout faire!!

Créons le bouton.

Dim Button1 As New Button


Modifions ses propriétés
Me.Button1.Location = New System.Drawing.Point(56, 144)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(104, 24)
Me.Button1.TabIndex = 0
Me.Button1.Text = "Button1"

Le bouton existe mais il faut l'ajouter à la collection Controls de la fenêtre (Cette collection contient tous les contrôles contenus dans la fenêtre):

Me.Controls.Add(Button1)


1.1.2. Ajouter des évènements.

Le bouton existe mais pour le moment, il ne gère pas les évènements.
Il faut inscrire le bouton dans une méthode de gestion d'évènements. En d'autres termes, Vb doit savoir quelle procédure évènement doit être déclenchée quand un évènement survient. Pour cela, il y a 2 méthodes:
Déclarer la variable avec le mot clé WithEvents ce qui permet ensuite d'utiliser le Handles du contrôle dans la déclaration d'une Sub:
Déclaration dans la partie déclaration du module(en haut) (WithEvents n'est pas accepté dans une procédure):
Private WithEvents Button1 As New Button
Remarque Button1 est accessible dans la totalité du module .
Puis écrire la sub évènement.
Sub OnClique ( sender As Object, EvArg As EventArgs) Handles Button1.Click
End Sub
Ainsi VB sait que pour l'évènement Button1.Click , il faut déclencher la Sub OnClique.
Il semble que quand on fait:Private WithEvents Button1 As Button (sans New) dans la partie déclaration puis DIM Button1 As New Button dans une procédure, la Sub OnClique ne fonctionne pas!!
C'est un problème de 'visibilité' donc bien faire Private WithEvents Button1 As New Button
Remarque: il pourrait y avoir plusieurs Handles sur une même sub, donc des évènements différents sur des objets différents déclenchant la même procédure.
Utiliser AddHandler
Déclaration (possible dans une procédure):
Dim Button1 As New Button
Puis écrire la gestion de l'évènement.( L'évènement Button1.click doit déclencher la procédure dont l'adresse est BouttonClique)
AddHandler Button1.Click, AddressOf BouttonClique
(ne pas oublier la virgule avant AddressOf)
Enfin on écrit la sub qui 'récupère ' l'évènement:
Private Sub BouttonClique (sender As Object, evArgs As EventArgs)
End Sub
Ainsi VB sait que pour un évènement du Button1 , il faut déclencher la Sub ButtonClique
Exemple avec AddHandler:
Créons un TextBox nommé TB et une procédure déclenchée par KeyUp de ce TextBox:
Dans une procédure (Button1_Click par exemple): Je crée un TextBox nommé TB, je le positionne, je met dedans le texte 'ici une textbox'. Je l'ajoute aux Contrôles du formulaire.
Grâce à 'AddHandler', je lie l'évènement Keyup de cet objet TB à la sub que j'ai crée :TextboxKeyup.

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim TB As New System.Windows.Forms.TextBox
TB.Location = New System.Drawing.Point(2, 2)
TB.Text = "ici une textBox"
Me.Controls.Add(TB)
AddHandler TB.Keyup, AddressOf TextboxKeyup.
End sub

Sub TextboxKeyup.(ByVal sender As Object, ByVal e As KeyEventArgs)
...
End Sub

Si je crée un autre bouton TB2, j'ajoute de la même manière AddHandler TB2.Click, AddressOf TextboxKeyup2, ainsi chaque évènement de chaque contrôle à ses propres routines évènement et en cliquant sur le bouton TB2 on déclenche bien TextboxKeyup2
Attention, la procédure TextboxKeyup doit recevoir impérativement les bons paramètres: un objet et un KeyEventArgs car ce sont les paramètres retournés par un KeyUp.
Autre exemple avec AddHandler mais avec 2 boutons:
Il est possible de créer plusieurs contrôles ayant la même procédure évènement:
Exemple: Créons 2 boutons (BT1 et BT2) déclenchant une seule et même procédures (BoutonClique).
Dans ce cas, comment savoir sur quel bouton l'utilisateur à cliqué ?
En tête du module déclarons les boutons (Ils sont public):
Public BT1 As New System.Windows.Forms.Button
Public BT2 As New System.Windows.Forms.Button


Indiquons dans form_load par exemple la routine évènement commune (BoutonClique) grâce a AddHandler.
Form_Load
BT1.Location = New System.Drawing.Point(2, 2)
BT1.Text = "Bouton 1"
Me.Controls.Add(BT1)
BT2.Location = New System.Drawing.Point(100, 100)
BT2.Text = "Bouton 2"
Me.Controls.Add(BT2)
AddHandler BT1.Click, AddressOf BoutonClique
AddHandler BT2.Click, AddressOf BoutonClique
End Sub


Si c'est le bouton 1 qui a été cliqué, afficher "button1" dans une TextBox:
Sub BoutonClique(ByVal sender As Object, ByVal e As EventArgs)
If sender Is BT1 Then
TextBox1.Text = "button 1"
ElseIf sender Is BT2 Then
TextBox1.Text = "button 2"
End If
End Sub
La ruse est que déterminer quel objet (quel bouton) à déclenché l'évènement, pour cela on utilise le premier paramètre, le sender;
If sender Is BT1 Then : Si le sender est le bouton1..
Noter bien:
- le mot clé handles permet d'associer un événement à une procédure au moment de la conception.
Le concepteur sait qu'une procédure doit gérer les événements (il peut y en avoir plusieurs).
- le mot clé addhandler permet d'associer un événement à une procédure au moment de l'exécution.
Ceci est utile dans un cadre producteur-consommateur d'événements. Un objet produit un événement qui doit informer d'autres objets; au cours de l'exécution on crée l'association entre l'évènement et une procédure.
Remarque importante:
Les Handler ne sont en fait libérés qu’au déchargement complet du programme (application.exit) et non à la fermeture de la fenêtre et des objets contenus dans celle-ci... Aussi , si vous ouvrez plusieurs fois un même formulaire possédant AddHandler sur un bouton, cela créera à chaque fois un Handler qui s'ajoute aux précédents et l'évènement se déclenchera plusieurs fois lors de l'appuie du bouton!!
Il faut donc utiliser RemoveHandler pour libérer le Handler. L’instruction s’utilise de la même façon que le AddHandler ! (reprendre les lignes d’ajout du handler et remplacer AddHandler par RemoveHandler) .


Pour la petite histoire, nous créons un délégué à chaque fois que nous créons une procédure gestionnaire d'évènement avec le mot Handles ou avec AddHandler.
En C on utilise des pointeurs de fonction , adresse en mémoire indiquant ou le logiciel doit sauter quand on appelle une fonction ou un évènement. En VB on parle de délégué.

Les contrôles de type ListBox

1.1. Utiliser les contrôles de type liste (sélection, vue, images, …)

1.1.1. Les ListBox

Le contrôle ListBox affiche une liste d'éléments (d'objets) dans laquelle l'utilisateur peut faire un ou plusieurs choix.
La liste contient "tarte", "poisson", "viande", "légumes", "sauces".
Ici l'élément "poisson" est sélectionné, la ligne correspondante est en bleu.

La listBox contient une collection d'"Item":
Elle est vide au départ.
Si j'ajoute un élément à la ListBox, cela ajoute un élément à la collection Items

ListBox1.Items est une collection contenant tous les éléments (les objets) chargés dans la liste.
La propriété Items.Count indique le nombre d'éléments contenus dans la liste . Attention le premier élément est toujours l’élément 0, aussi le nombre d’éléments est égal au numéro de l'élément le plus haut plus un.
Pour ajouter ou supprimer des élements dans un contrôle ListBox

Utilisez la méthode Items.Add, Items.Insert, Items.Clear ou Items.Remove. En mode conception, vous pouvez également utiliser la propriété Items.

Exemples :
Vider la ListBox:
ListBox1.Items.Clear()

Ajouter l'élément "poisson"
ListBox1.Items.Add("poisson")
Ajouter '4'
ListBox1.Items.Add(4.Tostring)
ou
ListBox1.Items.Add(4) 'accepté car les items sont des objets.
Insérer 'lulu en 4éme position
ListBox1.Items.Insert(4, "lulu")
Les listBox acceptent des objets, elles affichent généralement ce qu'il y a dans la propriété 'Text' de l'objet.

Charger dans une ListBox les nombres de 1 à 100
For i = 1 To 100
ListBox1.Items.Add(i.ToString)
Next i

Comment enlever des éléments?
' Enlever l'élément d'index 5:ListBox1.Items.RemoveAt(5)
' Enlever l'élément sélectionné:ListBox1.Items.Remove(ListBox1.SelectedItem)
' Enlever l'élément "Tokyo":ListBox1.Items.Remove("Tokyo")

Comment lire l'élément 3?

Dim t As String
t=ListBox1.Items(3).ToString
(En Option=Strict il est nécessaire de transformer l'objet Items(3) en String avec .ToString)

Comment rechercher l'élément qui contient une chaîne de caractères?
Dim x As Integer
x=List1.FindString("pa") retourne le numéro du premier élément commençant par 'pa'.
x=List1.FindString("pa",12) retourne le numéro de l'élément commençant par 'pa' en cherchant à partir de l'élément numéro 12.
x=List1.FindStringExact("papier") 'permet de rechercher l'élément correspondant exactement à la chaîne.

Comment sélectionner un élément par code?
ListBox1.SetSelected(x, True) 'la ligne contenant x devient bleue

L’utilisateur double-clique sur un des éléments, comment récupérer son numéro ?

Grâce à SelectedIndex.
Private Sub ListBox_DoubleClick.
N=ListBox1.SelectedIndex
End If

‘N contient le numéro de l’élément sélectionné. Attention comme d’habitude, si je sélectionne la troisième ligne c’est en faite l’élément numéro 2.
SelectedIndex retourne donc un entier correspondant à l'élément sélectionné dans la zone de liste. Si aucun élément n'est sélectionné, la valeur de la propriété SelectedIndex est égale à -1.
La propriété SelectedItem retourne l'élément sélectionné ("poisson" dans l'exemple si dessus).

Et la multi sélection, quels éléments ont été sélectionnés?
La propriété SelectionMode indique le nombre d'éléments pouvant être sélectionnés en même temps.
Lorsque plusieurs éléments sont sélectionnés, la valeur de la propriété SelectedIndex correspond au rang du premier élément sélectionné dans la liste. Les collections SelectedItems et SelectedIndices contiennent les éléments et les numéros d'index sélectionnées.
Si la propriété Sorted = True, la liste est triée automatiquement.

On peut 'charger' une ListBox automatiquement avec un tableau

En utilisant Datasource:
Dim LaList() As String = {"one", "two", "three"}ListBox1.DataSource = LaList
On peut aussi utiliser AddRange:
Dim Ite(9) As System.ObjectDim i As IntegerFor i = 0 To 9Ite(i) = "Item" & iNext i
ListBox1.Items.AddRange(Ite)
Comment 'charger' une ListBox automatiquement à partir d'un fichier texte.
ListBox1.Items.AddRange(System.IO.File.ReadAllLines("c:\list.txt"))
(le fichier list.txt est un fichier .txt crée avec NotePad par exemple et contenant les items séparés par des retours à la ligne"
Exemple de fichier:
"philippe
paul
jean
luc"


Comment connaître l'index de l'élément que l'on vient d'ajouter? (et le sélectionner)
Dim x As Integerx = List1.Items.Add("Hello")List1.SelectedIndex = x
On utilise la valeur retournée (x dans notre exemple) par la méthode Add.
(NewIndex n'existe plus en VB.NET)


Comment affecter à chaque élément de la liste un numéro, une clé?

Exemple : Dans un programme, chaque utilisateur a un nom et un numéro; je charge dans une ListBox la liste du nom des utilisateurs; quand on clique sur la liste, je veux récupérer le numéro de l'utilisateur (pas l'index de l'élément).
Comment donc, à chaque élément de la Listbox, associer un numéro (différent de l'index).

- En VB6 on utilisait une propriété (ListBox.ItemData()) pour lier à chaque élément de la ListBox un nombre (une clé); cela n'existe plus en VB.Net!!
Il existe des fonctions de compatibilité VB6, mais il faut éviter de les utiliser:
VB6.SetItemData(ListBox1, 0, 123) 'pour lier à l'élément 0 la valeur 123.

- Une alternative, pas très élégante:
Ajouter l'élément "toto"+chr$(9)+chr$(9)+ clé (clé n'est pas visible car les caractères de tabulation l'ont affichée hors de la Listbox)
Quand l'utilisateur clique sur la ligne, on récupère la partie droite donc la clé.
On peut aussi utiliser un Listview avec 2 colonnes; la seconde colonne servant à stocker le numéro.

- Une solution plus élégante:
On utilise le Tag du ListBox (Le Tag est une propriété qui peut contenir un objet (un tableau par exemple; chaque élément de ce tableau va contenir le numéro de l'utilisateur.)

Dim pos As Integer
ReDim ListBox1.Tag(100) 'Création du tableau dans le Tag

pos = ListBox1.Items.Add("Utilisateur1") 'On ajoute le nom de l'utilisateur1, pos est l'index de l'élément ajouté
ListBox1.Tag(pos) = 1 'On ajoute dans le Tag le numéro de l'utilisateur
pos = ListBox1.Items.Add("Utilisateur2")
ListBox1.Tag(pos) = 2
pos = ListBox1.Items.Add("Utilisateur3")
ListBox1.Tag(pos) = 3

'Quand l'utilisateur double-clique dans la liste, on récupère le numéro correspondant
Private Sub ListBox1_DoubleClick()
MsgBox(ListBox1.Tag(ListBox1.SelectedIndex))
End Sub

La contrainte est qu'il faut connaître le nombre maximum d'élément à charger et charger la liste dans l'ordre; il faut être en Option Strict=Off (sinon il y a liaison tardive).

Quand on charge une ListBox directement avec une base de données, il y a une solution pour gérer une clé.

Remarque:
Lorsque la propriété MultiColumn a la valeur true, la liste s’affiche avec une barre de défilement horizontale. Lorsque la propriété ScrollAlwaysVisible a la valeur true, la barre de défilement s'affiche, quel que soit le nombre d'éléments.

Comment à partir des coordonnées de la souris connaître l'élément de la liste qui est survolé?

Exemple: La souris survole ListBox2 , on a e.X et e.Y, coordonnées de l'écran, comment obtenir l'index.
On va d'abord transformer e.X et e.Y en coordonnées client (par rapport à la listBox)
ListBox2.PointToClient(New Point(e.X, e.Y)
Puis ListBox2.IndexFromPoint() va retourner l'index survolé.

Private Sub ListBox2_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox2.DragOver
IndexdInsertion = ListBox2.IndexFromPoint(ListBox2.PointToClient(New Point(e.X, e.Y)))
End Sub

Les propriétés d'un formulaire

1.1.1. Définir les propriétés d’un formulaire

Lors de la création de l’interface utilisateur d’une application Visual Basic, vous devez définir les propriétés des objets que vous créez.

Vous pouvez définir les propriétés de formulaire soit en écrivant du code, soit en utilisant la fenêtre Propriétés. Tous les paramètres définis au moment de la conception-lorsque vous créez l’application-servent de paramètres initiaux à chaque nouvelle exécution de votre application.

! Pour définir les propriétés de formulaire lors de la conception.
1. Si la fenêtre Propriétés n’est pas ouverte, dans le menu Affichage, cliquez sur Fenêtre Propriétés.
2. Dans la vue Conception, cliquez sur le formulaire dont vous voulez définir une propriété. Le nom du formulaire apparaît dans la liste déroulante Objet en haut de la fenêtre Propriétés.
3. Utilisez les boutons Alphabétique et Par catégorie de la fenêtre Propriétés pour afficher les propriétés du formulaire dans l’ordre alphabétique ou par catégorie.
4. Dans la fenêtre Propriétés, cliquez sur la propriété que vous souhaitez définir. Lorsque vous cliquez sur une propriété, sa description s’affiche au bas de la fenêtre Propriétés, dans le volet Description.
5. Tapez ou sélectionnez la valeur que vous voulez donner à la propriété.
6. Pour voir l’impact du nouveau paramètre sur le formulaire, vous pouvez exécuter votre application en cliquant sur le bouton Démarrer dans la barre d’outils standard

Le tableau suivant décrit certaines des propriétés de formulaire les plus généralement définies lors de la conception.


Lorsque vous démarrez un nouveau projet, Visual Basic considère que Form1 est l’objet de démarrage par défaut de votre projet. Si vous modifiez la propriété Name de Form1, vous devez aussi donner le même nom à l’objet de démarrage de votre projet, sinon le projet ne démarrera pas correctement.

! Pour modifier l’objet de démarrage de votre projet
1. Si l’Explorateur de solutions n’est pas ouvert, dans le menu Affichage, cliquez sur Explorateur de solutions.
2. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le nom du projet, puis cliquez sur Propriétés.
3. Dans la zone Objet de démarrage, cliquez sur le nouvel objet de démarrage de votre projet.

Les interfaces ratées

1.1. Conséquences d’une interface ratée et avantages d’une interface réussie

Une interface ratée produit entre autres conséquences

- Un sentiment de confusion lors de l’expérience utilisateur avec l’application
- Dénote un manque de professionnalisme de l’équipe de développement
- Un manque de sérieux du chef de projet
L’interface utilisateur réussie met immédiatement en confiance le client d’autant plus qu’elle constitue son premier contact avec l’application