Soyez le premier à donner votre avis sur cette source.
Snippet vu 18 568 fois - Téléchargée 28 fois
/// <summary> /// Stock the ClientID of the control to find /// </summary> private static String _clientID; /// <summary> /// Obtain a control from the ClientID /// </summary> /// <param name="page">You must pass the Page here</param> /// <param name="ClientID">the ClientID of the control you search</param> /// <returns>the Control matching the clientID, if not found return null</returns> /// <example> /// Control c = Utils.getControlsFromClientID(Page, "Panel1_Lbl1"); /// </example> /// <remarks>Must be called after the page_init, before the tree of Control isn't construct</remarks> internal static Control getControlFromClientID(Page page, String ClientID) { _clientID = ClientID; Control c = page.FindControl(ClientID); if (c != null) return c; return getControlFromClientIDInternal(page); } /// <summary> /// Obtain a control from a container /// </summary> /// <param name="Container"></param> /// <returns>use recursivity</returns> /// <remarks>the _clientID params is extern to not put into stack the value each call : better performance</remarks> private static Control getControlFromClientIDInternal(Control Container) { Control c; if (_clientID.Length > Container.ClientID.Length) { c = Container.FindControl(_clientID.Remove(0, Container.ClientID.Length + 1)); if (c != null) return c; } foreach (Control child in Container.Controls) { if (child.Controls.Count > 0) { c = getControlFromClientIDInternal(child); if (c != null) { _clientID = string.Empty; return c; } } } return null; }
21 oct. 2008 à 16:31
J'ai ajouté une condition avant de renvoyer le contrôle trouvé pour vérifier que le ClientID du control trouvé est identique à celui cherché, j'ai rencontré le problème dans le cas d'un repeater où le contrôle renvoyé était toujours le premier, j'ai également modifié les métodes pour ne plus utiliser l'attribut static ni de string '_clientid':
private Control getControlFromClientID(Page page, string ClientID)
{
Control c = page.FindControl(ClientID);
if (c != null)
return c;
return getControlFromClientIDInternal(page, ClientID);
}
private Control getControlFromClientIDInternal(Control Container, string ClientID)
{
Control c;
if (ClientID.Length > Container.ClientID.Length)
{
c = Container.FindControl(ClientID.Remove(0, Container.ClientID.Length + 1));
if (c != null)
if (c.ClientID == ClientID)
return c;
}
foreach (Control child in Container.Controls)
{
if (child.Controls.Count > 0)
{
c = getControlFromClientIDInternal(child, ClientID);
if (c != null)
if (c.ClientID == ClientID)
{
ClientID = string.Empty;
return c;
}
}
}
return null;
}
J'utilise ce code pour rechercher des contrôles dans une page ayant une master page et sachant que le contrôle est inclus dans deux repeater imbriqués.
++
21 déc. 2007 à 11:19
Je suis tombée sur un cas qui pose un problème (en vb.Net en tout cas):
- la CheckBoxList.
En effet, lorsque dans le processus de recherche d'un contrôle, "il" tombe sur une CBL, il effectue le getControlFromClientIDInternal, puisque que la CBL contient des CheckBox.
Et c'est là qu'il y a à mon avis un Bug(un bug vb j'entends!), car dans ce cas, la ligne
c = Container.FindControl(_clientID.Remove(0, Container.ClientID.Length + 1));
renvoie TOUJOURS la CheckBoxList en question !
j'ai même essayé dans la trace de mettre c = Container.FindControl("toto"), ça marche aussi !!...
j'ai donc ajouté une condition:
if (_clientID.Length > Container.ClientID.Length)
{
-> if (Container.GetType().ToString() != "System.Web.UI.WebControls.CheckBoxList" )
{
c = Container.FindControl(_clientID.Remove(0, Container.ClientID.Length + 1));
if (c != null)
return c;
}
// else:
// {
// ici il faut gérer la recherche des checkbox d'une CBL, si c'est nécessaire
// (avec un for each je pense)
// }
}
En espérant avoir aidé quelqu'un...
Mais peut-être quelqu'un a une meilleure idée pour gérer ce cas !
@Plus :o)
6 juil. 2006 à 13:38
tiens moi au courant pour la mémoire, ca m'intéresse énormément.
yopyop
6 juil. 2006 à 13:06
pour ce qui est de ma page de test, je devais avoir une centaine de label dans un UC et une 50aine d'UC dans la page ...
Donc une trés grosse page :)
pour les temps, c'etait autour de 0,000150s pour ma méthode et 0,000800s pour ta méthode (en mode debug en plus) ... donc on essaye d'optimiser pour pas grand chose :-)
Le passage du _clientID est surement l'une des solutions que je vais adopter :p En ce qui concerne la mémoire utilisé, je vais essayer de trouver une astuce pour pouvoir comparer ca, car ca m'interesse :-)
6 juil. 2006 à 12:57
effectivement, je n'ai pas tout testé.
Mais il me semble que les les contrôles doivent toujours être dans entre les balises form.
Autrement, pour partir de la page directement il suffit de ne pas utiliser l'instruction
form = FindFormControl(page); (mettre form=Page devrait enlever le bug).
Concernant la rapidité, je peux certainement améliorer ca (mais g pas le temps pour l'instant, surtout de créer la page de test. Environs combien de contrôles ? 5 fois plus rapide, mais genre on passe de 1 à 5 secondes ou de 0.1 seconde à 0.5 ?).
bref ... j'ai au moins montré comment parcourir un arbre sans récursivité, ce qui à mon avis est intéressant ... non ?
Concernant ton static, pourquoi ne passes-tu pas le ClientID en paramètre ?
private static Control getControlFromClientIDInternal(Control Container, ref String ClientId)
(je ne connais pas l'équivalent de ByRef en C#).
Avec ca ta variable n'est pas copiée en mémoire (juste la référence).
Concernant la mémoire sur le serveur, tout dépend de la fréquentation de ton application.
Sur les gros sites ca peut causer de gros problèmes (je prèfère ajouter 2-3 secondes de loading sur une page plutôt que d'empêcher 500 personnes de bosser pendant 30 minutes).
yopyop
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.