2010-02-05 4 views
8

C#manière facile à utiliser FindControl (« »)

Salut,

je développe des applications web C# pour quelques années et il y a une question que je continue à venir upagainst que je ne peux pas trouver une façon logique de résoudre.

J'ai un contrôle auquel je souhaite accéder dans le code, ce contrôle est profond dans le balisage; enterré au sein de ContentPlaceHolders, UpdatePanels, panneaux, GridViews, EmptyDataTemplates, TableCells (ou de toute autre structure que vous aimez .. le point est qu'il a plus de parents que de farteurs pour la justice).

Comment puis-je utiliser FindControl("") pour accéder à cette commande sans faire ceci:

Page.Form.Controls[1].Controls[1].Controls[4].Controls[1].Controls[13].Controls[1].Controls[0].Controls[0].Controls[4].FindControl(""); 

Répondre

12

Ecrivez une méthode d'assistance appelée FindControlRecursive tel que fourni par Jeff Atwood lui-même.

private Control FindControlRecursive(Control root, string id) 
{ 
    if (root.ID == id) 
    { 
     return root; 
    } 

    foreach (Control c in root.Controls) 
    { 
     Control t = FindControlRecursive(c, id); 
     if (t != null) 
     { 
      return t; 
     } 
    } 

    return null; 
} 

http://www.codinghorror.com/blog/archives/000307.html

+0

+1 tâche parfaite pour récursion –

+0

Juste un commentaire à se méfier de la baisse de performance si vous abusez de la récursivité. Certainement encore un +1. –

+0

Bravo, juste l'astuce :) – WillDud

3

utilisation récursive FindControl:

public T FindControl<T>(string id) where T : Control 
    { 
     return FindControl<T>(Page, id); 
    } 

    public static T FindControl<T>(Control startingControl, string id) where T : Control 
    { 
     // this is null by default 
     T found = default(T); 

     int controlCount = startingControl.Controls.Count; 

     if (controlCount > 0) 
     { 
      for (int i = 0; i < controlCount; i++) 
      { 
       Control activeControl = startingControl.Controls[i]; 
       if (activeControl is T) 
       { 
       found = startingControl.Controls[i] as T; 
        if (string.Compare(id, found.ID, true) == 0) break; 
        else found = null; 
       } 
       else 
       { 
        found = FindControl<T>(activeControl, id); 
        if (found != null) break; 
       } 
      } 
     } 
     return found; 
    } 
0

Ou dans LINQ:

 private Control FindControlRecursive(Control root, string id) 
     { 
      return root.ID == id 
         ? root 
         : (root.Controls.Cast<Control>() 
          .Select(c => FindControlRecursive(c, id))) 
          .FirstOrDefault(t => t != null); 
     } 
Questions connexes