février
2008
Lorsqu’on a des imbrications de controles utilisateurs on peut se retrouver avec des problèmes d’enchainement des événements, un OnLoad arrivant avant un autre (alors qu’on aurait aimé le contraire bien sur ! ).
Pour illustrer ce propos, voyons un exemple ultra simpliste : une page qui contient un controle utilisateur qui affiche des produits, qui lui meme contient un controle utilisateur qui a pour but de filtrer les produits.
Soit une page Default.aspx qui contient (code abrégé pour plus de lisibilité)
<form id="form1" runat="server">
<Affiche:Produit runat="server" ID="AfficheProduit" />
</form>
Dans son OnInit, on initialise les produits du controle utlisateur :
{
AfficheProduit.Produits = new List<Produit>(new Produit[] {new Produit("Appareil photo", 200), new Produit("Télé", 100)});
base.OnInit(e);
}
Dans le premier controle utilisateur, qui a pour charge d’afficher les produits et qui contiendra le controle utilisateur qui a pour but de filtrer les produits et un repeater qui affiche donc les produits :
<Filtre:Produit runat="server" ID="FiltreProduit" />
<asp:Repeater runat="server" ID="RepeaterProduit">
<ItemTemplate>
<asp:Label runat="server" Text="<%#Container.DataItem %>" /><br />
</ItemTemplate>
</asp:Repeater>
Nous verrons plus loin le OnLoad de ce controle utilisateur
Et enfin le controle utilisateur de filtre, qui ici n’affiche rien, mais il pourrait très bien afficher les différents choix de filtre.
Et son OnLoad :
{
List<Produit> produitFiltres = new List<Produit>();
foreach (Produit produit in _produits)
{
if (produit.Prix < 150)
{
produitFiltres.Add(produit);
}
}
_produits = produitFiltres;
base.OnLoad(e);
}
Le code, volontairement simpliste, a pour but de renvoyer les produits dont le prix est inférieur à 150 €
En ce qui concerne le controle utilisateur d’affiche des produits, on serait donc tenté par écrire quelque chose du genre :
{
FiltreProduit.Produits = _produits;
_produits = FiltreProduit.Produits;
RepeaterProduit.DataSource = _produits;
if (!IsPostBack)
RepeaterProduit.DataBind();
base.OnLoad(e);
}
Donc, dans l’ordre, affectation des produits au controle utilisateur de filtre.
Récupération des produits filtrés.
Et affectation au repeater.
Sauf que bien sur, ca ne peut pas marcher, le OnLoad du controle utilisateur de filtre sera appelé après le OnLoad d’affichage des produits et en aucun cas, la deuxième ligne pourra avoir un contenu cohérent.
On pourrait bien sur faire l’affectation et le DataBind dans le OnPreRender, mais ce n’est pas sa place (et puis le but est de voir l’utilisation d’un delegate ).
Comment faire alors pour que nous ayons une partie du code du OnLoad du controle d’affichage des produits ci-dessus qui soit appelé APRES celui du controle utilisateur de filtre ?
Une solution est d’avoir recours aux délégates. Et ici, en l’occurence à un délégate anonyme.
Remplacez le code du OnLoad par celui-ci :
{
FiltreProduit.Load += delegate
{
_produits = FiltreProduit.Produits;
RepeaterProduit.DataSource = _produits;
if (!IsPostBack)
RepeaterProduit.DataBind();
};
FiltreProduit.Produits = _produits;
base.OnLoad(e);
}
En rajoutant un délégate au OnLoad du controle utilisateur de filtre, on permet à la méthode du délégate d’etre appelée au moment du base.OnLoad(e) du controle utilisateur de filtre. Ce qui fait que la liste des produits pourra etre mise à jour après le passage du filtre.
Et ainsi, nous obtenons le comportement cherché.
Vous pouvez retrouver l’exemple complet ainsi que la classe Produit en téléchargement (20 Ko)
Commentaires récents
- [Tests] Arrange Act Assert, une traduction ? dans
- [UnitTest][C#] Tester une méthode privée dans
- Récupérer une valeur d’un contrôle depuis une autre Form / inclusions croisées et déclaration anticipée dans
- Tutoriel : Utiliser la ListBox et l’Isolated Storage dans vos applications Windows Phone 7 avec Silverlight dans
- Tutoriel : Utiliser la ListBox et l’Isolated Storage dans vos applications Windows Phone 7 avec Silverlight dans
Archives
- janvier 2013
- avril 2012
- janvier 2012
- juin 2011
- janvier 2011
- décembre 2010
- novembre 2010
- septembre 2010
- juin 2010
- mars 2010
- février 2010
- janvier 2010
- décembre 2009
- novembre 2009
- octobre 2009
- septembre 2009
- août 2009
- juillet 2009
- mai 2009
- avril 2009
- mars 2009
- janvier 2009
- décembre 2008
- novembre 2008
- octobre 2008
- septembre 2008
- août 2008
- juillet 2008
- juin 2008
- mai 2008
- avril 2008
- mars 2008
- février 2008
- janvier 2008
- décembre 2007
- novembre 2007
- octobre 2007
- septembre 2007
- août 2007
- juillet 2007
- juin 2007
- mai 2007