Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Atteint de JavaScriptite Aiguë [Cyril Durand]

Expert ASP.net Ajax et WCF, Cyril Durand parle dans son blog de point techniques sur ASP.net, ASP.net Ajax, JavaScript, WCF et .net en général. Cyril est également consultant indépendant, n'hésitez pas à le contacter pour de l'assistance sur vos projets

Actualités

  • Blog de Cyril DURAND, passionné de JavaScript, Ajax, ASP.net et tout ce qui touche au developpement Web Client-Side.

    N'hésitez pas à me contacter pour vos projets .net : architecture, accompagnement, formation, ...

    View Cyril Durand's profile on LinkedIn
    hit counters


    Expertise Commerce server et BizTalk

La methode FindControl

La méthode FindControl permet de trouver un contrôle à partir de son ID. Sans que l'on s'en rende compte, on l'utilise de plus en plus souvent. En effet ASP.net Ajax l'utilise très souvent en interne, ainsi lorsque l'on définit un trigger sur un UpdatePanel ou lorsque l'on renseigne la propriété AssociatedUpdatePanelID d'un UpdateProgress voir encore la propriété TargetControlID d'un extender, alors ASP.net utilise la méthode FindControl.

<asp:Button ID="btn1" runat="server" Text="go" OnClick="btn1_Click" /> <asp:UpdatePanel ID="up1" runat="server" > <ContentTemplate> <%=DateTime.Now.ToLongTimeString()%> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="btn1" /> </Triggers> </asp:UpdatePanel> <asp:updateprogress id="upg1" runat="server" AssociatedUpdatePanelID="up1"> <ProgressTemplate> En cours ... </ProgressTemplate> </asp:updateprogress>

Il est donc intéressant de savoir comment fonctionne cette méthode en détail. La description de la méthode FindControl dans msdn nous donne très peu d'information :

Searches the current naming container for a server control with the specified id parameter.

En utilisant Reflector on comprend mieux comment fonctionne cette méthode. Pour vous l'expliquer, voici une version simplifiée de son code :

protected virtual Control FindControl(string id) { // vérification que les contrôles enfants sont bien créer this.EnsureChildControls(); /// this.flags[0x80] est vrai seulement si l'instance en cours implémente INamingContainer /// ce bloc nous informe que la méthode FindControl appelle la méthode FindControl /// de son NamingContainer ou de lui même s'il implémente INamingContainer if (!this.flags[0x80]) { Control namingContainer = this.NamingContainer; if (namingContainer != null) { return namingContainer.FindControl(id, pathOffset); } return null; } // this._occasionalFields.NamedControls est un dictionnaire d'id/control qui contient // tous les contrôles du namingContainer en cours if (this.HasControls() && (this._occasionalFields.NamedControls == null)) { /// Cette méthode va au final appeler la méthode FillNamedControlsTable qui est /// une fonction récursive ajoutant dans le dictionnaire _occasionalFields.NamedControls /// tous les contrôles enfants à l'exception des enfants des contrôle implémentant /// l'interface INamingContainer ou des contrôles dont l'id n'a pas été spécifié. this.EnsureNamedControlsTable(); } int num = id.IndexOfAny(new char[] { '$', ':' }); /// si l'id ne contient pas le caractère $ ou : alors on retourne directement le contrôle /// présent dans le namingcontainer en cours if (num == -1) { // retourne l'élément demandé du dictionnaire return (this._occasionalFields.NamedControls[id] as Control); } /// sinon on cherche le contrôle "parent" puis on recherche via la méthode FindControl /// l'id sur le contrôle "parent". En vrai c'est implémenté différemment mais /// c'est l'idée qu'il faut retenir else { return ((Control)this._occasionalFields.NamedControls[id]).FindControl( id.Substring(num + 1,id.Length - num)); } }

La première chose intéressante est que la méthode FindControl recherche les contrôles contenus par les NamingContainer c'est à dire les contrôles qui implémente INamingContainer. La seconde chose, est que si l'on veut faire une recherche d'un namingcontrol à un autre on peut avoir une notion de hiérarchie en utilisant les symboles $ ou : pour séparer les contrôles.

Par exemple le contrôle Login implémente INamingContainer puisqu'il hérite de CompositeControl. Ce contrôle est constitué de différentes textbox. Si l'on veut récupérer l'instance d'une textbox on peut alors faire :

// contient l'instance de la textbox du password contenu dans le controle login TextBox tbPassword = (TextBox)Page.FindControl("login1:Password");

Lorsque l'on définit un trigger sur un UpdatePanel :

<Triggers> <asp:AsyncPostBackTrigger ControlID="btn1" /> </Triggers>

On utilise au final la méthode ControlUtil.FindTargetControl :

internal static Control FindTargetControl(string controlID, Control control, bool searchNamingContainers) { if (searchNamingContainers) { Control namingContainer = control; Control control2 = null; while ((control2 == null) && (namingContainer != control.Page)) { namingContainer = namingContainer.NamingContainer; if (namingContainer == null) { return control2; } control2 = namingContainer.FindControl(controlID); } return control2; } return control.FindControl(controlID); }

Le paramètre controlID correspond à la valeur de la propriété ControlID, control est l'UpdatePanel sur lequel on a ajouté le trigger et searchNamingContainers est vrai dans le cas d'un AsyncPostBackTrigger et faux dans le cas d'un PostBackTrigger. Lorsqu'on utilise un AsyncPostBackTrigger on se rend alors compte que la recherche se fait en remontant les NamingContainer.

Posted: samedi 23 juin 2007 17:54 par cyril
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Commentaires

Jacksparoow a dit :

merci cyril pour cet article ça aide bouceaup sauf que j'ai une question à propos de cette recherche de control est ce que le trigger de l'updatepanel est capable de trouver un control qui exsite dans un autre NaminContainer?

merci

# mai 10, 2008 21:01

cyril a dit :

Ta question n'est pas assez précise, quelle genre de trigger, un asyncpostbacktrigger ou un postbacktrigger ?

Dans le cas d'un AsyncPostBackTrigger, l'UpdatePanel recherche d'abord via FindContrl dans son NamingContainer, s'il ne le trouve pas, il va chercher dans le namingContainer du namingContainer et ainsi de suite.

Tout est expliqué dans ce post, qui est en effet un poil technique :-)

# mai 10, 2008 22:44
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Merci par Blog de Jérémy Jeanson le 10-01-2019, 20:47

- Office 365: Script PowerShell pour auditer l’usage des Office Groups de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 11:02

- Office 365: Script PowerShell pour auditer l’usage de Microsoft Teams de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 10:39

- Office 365: Script PowerShell pour auditer l’usage de OneDrive for Business de votre tenant par Blog Technique de Romelard Fabrice le 04-25-2019, 15:13

- Office 365: Script PowerShell pour auditer l’usage de SharePoint Online de votre tenant par Blog Technique de Romelard Fabrice le 02-27-2019, 13:39

- Office 365: Script PowerShell pour auditer l’usage d’Exchange Online de votre tenant par Blog Technique de Romelard Fabrice le 02-25-2019, 15:07

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Stream Portal par Blog Technique de Romelard Fabrice le 02-21-2019, 17:56

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Video Portal par Blog Technique de Romelard Fabrice le 02-18-2019, 18:56

- Office 365: Script PowerShell pour extraire les Audit Log basés sur des filtres fournis par Blog Technique de Romelard Fabrice le 01-28-2019, 16:13

- SharePoint Online: Script PowerShell pour désactiver l’Option IRM des sites SPO non autorisés par Blog Technique de Romelard Fabrice le 12-14-2018, 13:01