Cours
3 – Les User Controls
Un User Control, ou contrôle utilisateur, est un template (un modèle) de contrôle créé par le développeur.
Il est représenté par une classe dérivée de la classe System.Web.UI.UserControl.
Au même titre qu’un contrôle serveur ASP.NET, on peut l’utiliser dans tous les WebForms du projet dans lequel il est créé.
Un User Control est un contrôle composé de un ou plusieurs autres contrôles.
Il peut ainsi contenir des Labels, des TextBoxs, des DropDownLists, …
Il peut aussi déclencher des événements.
3.1 – Création d’un contrôle utilisateur
Dans le projet Web, on ajoute un nouvel élément du type Contrôle utilisateur Web.
Cet élément porte l’extension .ascx. Exemple InfosProduit.ascx
De la même façon que pour un WebForm, un User Control est représenté par une classe et il donne lieu à une page « Design » et une page Code Behind.
La page Design comporte la ligne suivante (exemple) :
<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="InfosProduit.ascx.vb" Inherits="WebAppTest.InfosProduit" %>
Cette directive indique que :
-
nous sommes en présence d’un Control
-
le langage coté serveur est VB
-
Tous les événements ne seront pas automatiquement déclenchés
-
La page de code correspondante s’appelle InfosProduits.ascx.vb
-
L’espace de noms est WebAppTest.InfosProduit
Le code behind est lui aussi pré-rempli de façon classique:
VB:
Public Class InfosProduit
Inherits System.Web.UI.UserControl
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
End Sub
End Class
3.1.2 – Ajout de contrôles dans le User Contrôle
Nous pouvons ajouter des contrôles depuis la page Design et/ou depuis le code behind :
<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="InfosProduit.ascx.vb" Inherits="WebApplication30.InfosProduit" %>
<table>
<tr>
<td><asp:Image ID="Img_photo" runat="server" /></td>
<td><asp:Label ID="Lb_Designation" runat="server"></asp:Label></td>
<td>PU HT:<asp:Textbox ID="Tb_TarifHT" runat="server"></asp:Textbox></td>
<td>Qte:<asp:TextBox ID="Tb_Qte" runat="server"></asp:TextBox></td>
</tr>
</table>
Coté code behind, nous pouvons ajouter des méthodes permettant de gérer les propriétés des contrôles enfant du contrôle utilisateur.
Par exemple, nous pouvons implémenter une méthode permettant de remplir les contrôles avec des valeurs transmises depuis la page qui contiendra notre User Control.
VB:
Public Class InfosProduit
Inherits System.Web.UI.UserControl
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
End Sub
Public Sub Remplissage(ByVal img_url As String, ByVal designation As String,
ByVal tarif_ht As Double, ByVal qte As Integer)
Img_Photo.ImageUrl = img_url
Lb_Designation.Text = designation
Lb_TarifHT.Text = tarif_ht
Lb_Qte.Text = tarif_ht
End Sub
End Class
3.2 - Utilisation du contrôle utilisateur depuis un WebForm
Afin de pouvoir utiliser notre contrôle utilisateur InfosProduit, nous devons tout d’abord ajouter une directive dans la page du WebForm qui va l’utiliser.
Cette directive doit être placée après la directive Page et avant le DOCTYPE de la page.
<%@ register Src="~/InfosProduit.ascx" TagName="ProductDetail" TagPrefix="myUcs" %>
Src : donne le chemin du fichier qui définit le User Control
TagName : donne le nom qui servira à créer le User Control
TagPrefix : donne le préfixe qui sera placé devant le TagName pour créer le contrôle
3.2.1 – Création du contrôle dans le WebForm
Il ne reste plus qu’à créer la balise correspondante dans le <form> :
<body>
<form id="form1" runat="server">
<div>
<myUcs:ProductDetail id="IP1" runat="server"></myUcs:ProductDetail>
</div>
</form>
</body>
3.2.2 – Accès au contrôle depuis le code behind du WebForm
Notre contrôle utilisateur est accessible coté serveur du WebForm par le nom que nous lui avons donné dans son attribut ID (dans l’exemple : IP1)
Nous pouvons alors accéder à toutes les propriétés et méthodes définies dans la classe InfosProduit (dans la limitation des spécificateurs de portée déclarés).
Par exemple, nous allons remplir notre contrôle par l’appel à sa méthode Remplissage(…) :
VB:
Public Class ListeProduits
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
IP1.Remplissage("~/images/televiseur.jpg", "Téléviseur", 354.99, 5)
End Sub
End Class
3.3 – Propriétés du Contrôle Utilisateur
Un contrôle utilisateur étant une classe, nous pouvons lui ajouter des propriétés.
Les propriétés déclarées en tant que Public auront la spécificité d’être vues comme des attributs dans la balise de ce contrôle sur la page du WebForm appelant.
Cela nous permet de charger leur valeur lors de la définition de ce contrôle.
VB:
Public Class InfosProduit
Inherits System.Web.UI.UserControl
Public Property UcImageUrl As String = String.Empty
Public Property UcDesignation As String = String.Empty
Public Property UcTarifHT As Double = 0
Public Property UcQte As Integer = 0
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
Img_Photo.ImageUrl = UcImageUrl
Lb_Designation.Text = UcDesignation
Lb_TarifHT.Text = UcTarifHT
Lb_Qte.Text = UcQte
End If
End Sub
Public Sub Remplissage(ByVal img_url As String, ByVal designation As String,
ByVal tarif_ht As Double, ByVal qte As Integer)
Img_Photo.ImageUrl = img_url
Lb_Designation.Text = designation
Lb_TarifHT.Text = tarif_ht
Lb_Qte.Text = qte
End Sub
End Class
Dans le WebForm, coté Design, nous pouvons remplir directement les propriétés dans la balise du contrôle :
<form id="form1" runat="server">
<div>
<myUcs:ProductDetail id="IP1" runat="server"></myUcs:ProductDetail>
<myUcs:ProductDetail id="IP2" runat="server"></myUcs:ProductDetail>
<myUcs:ProductDetail id="IP3" runat="server" UcImageUrl="~/images/strato.jpg" UcDesignation="Guitare" UcTarifHT="1490.00" UcQte=3></myUcs:ProductDetail>
</div>
</form>
Dans le code, nous avons déplacé l’appel à la méthode de remplissage dans l’événement PostComplete du WebForm car cette méthode doit maintenant être appelée après l’événement Load du Contrôle.
Dans l’idéal, la méthode Remplissage devrait charger les propriétés avec les valeurs transmises.
VB:
Public Class ListeProduits
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
End Sub
Private Sub ListeProduits_LoadComplete(sender As Object, e As System.EventArgs) Handles Me.LoadComplete
IP1.Remplissage("~/images/televiseur.jpg.", "Téléviseur", 354.99, 5)
IP2.Remplissage("~/images/telephone.jpg.", "Téléphone de bureau", 463.15, 10)
End Sub
End Class
3.4 – Evénements du Contrôle utilisateur
Les contrôles définis dans le contrôle utilisateur peuvent déclencher des événements auquel nous pouvons réagir coté serveur.
Dans InfosProduit, transformons tout d’abord Img_Photo en un type ImageButton :
<table style="border: 1px solid #0000FF;">
<tr>
<td style="border: 1px solid #0000FF;width:120px;"><asp:Imagebutton ID="Img_Photo" runat="server" /></td>
<td style="border: 1px solid #0000FF;width:200px;"><asp:Label ID="Lb_Designation" runat="server"></asp:Label></td>
<td style="border: 1px solid #0000FF;width:100px;">PU HT:<asp:Label ID="Lb_TarifHT" runat="server"></asp:Label></td>
<td style="border: 1px solid #0000FF;width:100px;">Qte:<asp:Label ID="Lb_Qte" runat="server"></asp:Label></td>
</tr>
</table>
Coté serveur, modifions notre classe pour ajouter une propriété UcId, sa prise en compte dans les méthodes, et ajoutons la méthode Img_Photo_Click qui va gérer l’événement Click sur le contrôle Img_Photo :
VB :
Public Class InfosProduit
Inherits System.Web.UI.UserControl
Public Property UcId As Integer = 0
Public Property UcImageUrl As String = String.Empty
Public Property UcDesignation As String = String.Empty
Public Property UcTarifHT As Double = 0
Public Property UcQte As Integer = 0
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
Img_Photo.ImageUrl = UcImageUrl
Lb_Designation.Text = UcDesignation
Lb_TarifHT.Text = UcTarifHT
Lb_Qte.Text = UcQte
End If
End Sub
Public Sub Remplissage(ByVal id_product As Integer, ByVal img_url As String, ByVal designation As String,
ByVal tarif_ht As Double, ByVal qte As Integer)
UcId = id_product
Img_Photo.ImageUrl = img_url
Lb_Designation.Text = designation
Lb_TarifHT.Text = tarif_ht
Lb_Qte.Text = tarif_ht
End Sub
Private Sub Img_Photo_Click(sender As Object, e As System.Web.UI.ImageClickEventArgs) Handles Img_Photo.Click
Response.Redirect("EditProduit.aspx?id=" & UcId)
End Sub
End Class
Maintenant, sur la page ListeProduits, un clic sur une des images déclenchera la fonction Img_Photo_Click qui appellera le WebForm EditProduit.aspx en lui fournissant en paramètre l’Id du produit correspondant :
3.5 – Conclusion
Comme nous venons de le voir, un Contrôle personnalisé peut s’avérer très utile pour créer des groupes de contrôles dont on doit créer plusieurs instances, au sein de la même page (comme dans la liste de notre exemple) ou sur des pages différentes nécessitant les mêmes contrôles (adresse envoi, adresse facturation, adresse client, …)
Dans notre exemple, nous avons alimenté les valeurs de manière triviale.
Dans la pratique, notre contrôle utilisateur serait couplé à une classe métier permettant un accès à une base de données.
Un autre avantage des contrôles utilisateurs est le fait de pouvoir créer un design unique (avec les feuilles de style) pour toutes les instances de ce contrôle, garantissant l’homogénéité de l’interface graphique.