FAQ ASP.NET/VB.NET
FAQ ASP.NET/VB.NETConsultez toutes les FAQ
Nombre d'auteurs : 38, nombre de questions : 369, dernière mise à jour : 16 juin 2021
- Comment créer un contrôle utilisateur (User Control .ascx) ?
- Comment utiliser un contrôle utilisateur dans une page ?
- J'ajoute un contrôle dans mon user control et le compilateur ne le reconnait pas dans le code behind ?
- Je crée mon user control dynamiquement mais je n'arrive pas à accèder aux champs qu'il contient (null) ?
- Comment accéder aux propriétés d'un WebUserControl en code behind?
- Comment passer des paramètres à un userControl ?
- Comment passer des paramètres au constructeur d'un contrôle utilisateur ?
- Comment déclarer mon contrôle utilisateur pour qu'il soit déclaré dans toutes mes pages ?
- Puis-je afficher un UserControl directement dans mon navigateur ?
Un contrôle utilisateur (extension .ascx) est grosso modo une mini page (.aspx) qui peut s'inclure dans une page et qui ne comporte aucune des balises suivantes : <html><body><form>.
Un contrôle utilisateur a pour directive :
<
%@ Control Language=
"vb"
AutoEventWireup=
"false"
CodeBehind=
"monUserControl.ascx.cs"
Inherits
=
"monProjet.monUserControl"
%>
Pour l'ajouter depuis visual studio :
Click droit sur le projet, Add --> New Item -> Web User Control
L'IDE génère automatiquement la directive du contrôle utilisateur et le fichier source de code behind dont devra hériter le contrôle utilisateur.
NB : penser à mettre AutoEventWireup à false (voir A quoi sert AutoEventWireup ?)
Pour utiliser un contrôle utilisateur dans sa page, il faut utiliser la directive @register pour faire connaitre le contrôle utilisateur à la page :
<%
@ Register Src=
"~/monUserControl.ascx"
TagName=
"MonUserControl"
TagPrefix=
"UC"
%>
(NB : on peut préciser l'assembly qui contient l'userControl si celle-ci est différente en rajoutant l'attribut Assembly="....")
Pour l'insérer enfin dans sa page, on utilisera la combinaison TagPrefix:TagName :
<
UC:
MonUserControl runat=
"server"
/>
Cette dernière ligne de code devra bien sur être ajoutée entre les balises <form> et </form> de sa page.
Lorsque j'ajoute un contrôle (label) par exemple :
<
asp:Label ID=
"monLabel"
Text
=
"Mon text"
runat=
"server"
/>
L'IDE ajoute automatiquement dans la classe partielle (fichier .designer.cs)
Protected
WithEvents
monLabel As
System.Web.UI.WebControls.Label
Il peut arriver que l'ide n'arrive pas à ajouter ce membre en protected (source control qui bloque le fichier, lecture seule, etc ...)
Dans ce cas, il faudra le rajouter à la main dans ce même fichier
Vérifiez également qu'il ne soit pas déclaré en private.
Lorsque vous essayez d'accèder aux contrôles présents dans votre user control, vous obtenez l'exception : System.NullReferenceException
C'est que vous avez probablement cherché à instancier votre usercontrol avec new, de cette facon par exemple :
Dim
uc As
New
monUserControl
monPlaceHolder.Controls.Add
(
uc)
Ce n'est pas la bonne méthode.
Pour charger un UserControl, il faut utiliser LoadControl. La méthode LoadControl lit le fichier et l'instancie comme un contrôle pouvant être ajouté à la page.
Dim
uc As
monUserControl =
CType
(
LoadControl
(
"~/monUserControl.ascx"
), monUserControl)
monPlaceHolder.Controls.Add
(
uc)
Remarque : En général, il vaut mieux éviter de charger un contrôle utilisateur dynamiquement ; il vaudra mieux le placer dans la page aspx (ou un usercontrol ascx) quitte à le masquer dans le OnInit si on en a pas besoin suivant certaines conditions
Le mieux est de l'expliquer par un exemple:
Imaginons que nous développons un petit contrôle permet de rechercher dans la base
de données des utilisateurs. Ce qui nous interresse dans cette base sont le nom et le prénom
de la personne sélectionnée et d'utiliser ces valeurs dans un traitement quelconque.
Pour cela, il suffit de définir des propriétés au contrôle, par exemple:
Public
ReadOnly
Property
SelectedName
(
) As
String
Get
Return
DdlUsers.SelectedValue.Split
(
","
C)(
0
)
End
Get
End
Property
Public
ReadOnly
Property
SelectedFirstName
(
) As
String
Get
Return
DdlUsers.SelectedValue.Split
(
","
C)(
1
)
End
Get
End
Property
...
Dans la page qui héberge le WebControl, il suffit alors de lui donner la référence du WebControl:
Protected
Sp As
SearchPeople
Il suffit alors de l'utiliser comme tous les autres composants inclus dans asp.NET:
LaTest.Text
=
"Nom : "
+
Sp.SelectedName
+
", Prenom: "
+
Sp.SelectedFirstName
La solution la plus classique est de créer des propriétés publiques sur ce contrôle utilisateur et de les renseigner lors de l'ajout du contrôle utilisateur dans la page.
Source du contrôle utilisateur :
Public
Partial
Class
monUserControl
Inherits
System.Web.UI.UserControl
Private
_maValeur As
String
Public
Property
MaValeur
(
) As
String
Get
Return
_maValeur
End
Get
Set
(
ByVal
value As
String
)
_maValeur =
value
End
Set
End
Property
Protected
Overrides
Sub
OnLoad
(
ByVal
e As
System.EventArgs
)
monLabel.Text
=
_maValeur
MyBase
.OnLoad
(
e)
End
Sub
End
Class
dans la page.aspx
<
UC:MonUserControl runat=
"server"
MaValeur=
"une valeur"
/>
NB : cet exemple initialise la propriété MaValeur à un label dans le onInit. Il aurait pu être judicieux évidement d'utiliser un databinding avec # (voir Qu'est-ce que le scriptlet d'expressions liées <%# expression %>?)
voir aussi : comment passer des paramètres au constructeur d'un contrôle utilisateur
On peut être tenté lors du chargement dynamique d'un contrôle utilisateur d'utiliser un constructeur qui a des paramètres au lieu de créer des propriétés et de les renseigner.
Prenons ce contrôle utilisateur par exemple :
Public
Partial
Class
monUserControl
Inherits
System.Web.UI.UserControl
Private
_maValeur As
String
Public
Sub
New
(
)
End
Sub
Public
Sub
New
(
ByVal
maValeur As
String
)
_maValeur =
maValeur
End
Sub
Protected
Overrides
Sub
OnLoad
(
ByVal
e As
System.EventArgs
)
If
(
String
.IsNullOrEmpty
(
_maValeur)) Then
monLabel.Text
=
"Valeur par défaut"
Else
monLabel.Text
=
_maValeur
End
If
MyBase
.OnLoad
(
e)
End
Sub
End
Class
Si on charge ce contrôle utilisateur sans passer de paramètres au constructeur, on aura une valeur par défaut ; sinon on utilisera la valeur passée.
On a bien noté qu'il fallait utiliser LoadControl lors d'un chargement dynamique de contrôle utilisateur (voir Je crée mon user control dynamiquement mais je n'arrive pas à acceder aux champs qu'il contient (null) ?)
Voici une fonction statique qui s'occupe d'instancier le contrôle utilisateur avec des paramètres dans le constructeur, en utilisant la reflexion
Public
Shared
Function
LoadControl
(
ByVal
page As
Page, ByVal
pathControleUtilisateur As
String
, _
ByVal
ParamArray
parametresConstructeur As
String
(
)) As
UserControl
Dim
constParamTypes As
New
List
(
Of
Type
)
For
Each
constParam As
Object
In
parametresConstructeur
constParamTypes.Add
(
constParam.GetType
(
))
Next
Dim
uc As
UserControl =
CType
(
page.LoadControl
(
pathControleUtilisateur), UserControl)
' trouve le constructeur
Dim
constructeur As
ConstructorInfo =
uc.GetType
(
).BaseType.GetConstructor
(
constParamTypes.ToArray
(
))
' et l'invoke
If
(
constructeur Is
Nothing
) Then
Throw
New
MemberAccessException
(
"Contrôle utilisateur non trouvé : "
+
uc.GetType
(
).BaseType.ToString
(
))
Else
constructeur.Invoke
(
uc, parametresConstructeur)
End
If
Return
uc
End
Function
A utiliser ainsi :
Dim
uc As
monUserControl =
CType
(
LoadControl
(
Page, "~/monUserControl.ascx"
, "Ma valeur passée"
), monUserControl)
monPlaceHolder.Controls.Add
(
uc)
NB : ne pas oublier de créer également un constructeur par défaut, sinon vous aurez l'erreur suivante
CS1501: Aucune surcharge pour la méthode 'monUserControl' ne prend d'arguments '0'
Cela se passe dans le web.config, à la section pages/controls.
<
system.web
>
<
pages>
<
controls>
<
add tagPrefix=
"cc1"
src=
"~/controls/ctl1.ascx"
tagName=
"monUc"
/>
</
controls>
</
pages>
</
system.web
>
A utiliser ainsi dans une page :
<
cc1:monUc ID=
"MonUserControl"
runat=
"server"
/>
Non ce n'est pas possible. Un user control est prévu pour être ajouté dans une Webform (.aspx).
Pour le visualiser, vous devez donc l'ajouter à une page web et afficher cette page dans le browser.