2009-04-01 7 views
1

J'ai un TemplateField qui est dynamiquement ajouté à un GridView personnalisé.Quand un contrôle dans un TemplateField ajouté par programmation a-t-il sa propriété 'ID'?

void ITemplate.InstantiateIn(System.Web.UI.Control container) 
    { 
     switch (_templateType) 
     { 
      case ListItemType.Header: 
       if (this.ParentGridView.ShowDeleteHeaderImage) 
       { 
        Image hImg = new Image(); 
        hImg.ImageUrl = this.ParentGridView.DeleteHeaderImageUrl; 
        hImg.AlternateText = "Mark for Deletion"; 
        container.Controls.Add(hImg); 
       } 
       else 
       { 
        Label l = new Label(); 
        l.Text = "Del"; 
        container.Controls.Add(l); 
       } 
       break; 
      case ListItemType.Item: 
       container.Controls.Add(new CheckBox()); 
       break; 
      case ListItemType.EditItem: 
       break; 
      case ListItemType.Footer: 
       QLImageButton deleteButton = new QLImageButton(); 
       deleteButton.Settings.ImageId = "cmdQLGVDelete"; 
       deleteButton.Settings.ImageUrl = this.ParentGridView.DeleteImageUrl; 
       deleteButton.CommandName = "Delete"; 
       container.Controls.Add(deleteButton); 
       break; 
     } 
    } 

En réponse à une grille de commande (insertion/mise à jour/suppression), une méthode appelée GetRowControls est appelée qui le fait passer les colonnes du GridRow particulier, et ajoute chacun de ses contrôles à un dictionnaire.

Dictionary<string, WebControl> GetRowControls(GridViewRow row) 
... 

rowControls.Add(ctrl.ID, (WebControl)ctrl); 

... 

donc ceci fonctionne très bien pour les deux champs du modèle et des contrôles liés ajoutés déclarative, ainsi que des champs de modèle non-dynamique ajouté programatically.

Cependant, lorsque le contrôle est un contrôle TemplateField ajouté dynamiquement, ctrl.ID est toujours nul et donc l'instruction ci-dessus renvoie une exception.

J'ai examiné cela avec Reflector parce que j'ai trouvé que quand j'ai examiné la variable dans la fenêtre immédiate dans VS 2005 c.-à-d.? Ctrl, ctrl.ID listerait une valeur. J'ai depuis établi que c'est parce que dans la liste? Ctrl dans la fenêtre immédiate, le clientID Proprty est appelé et ClientID appelle EnsureId(), qui à son tour définit ID.

public virtual string ClientID 
{ 
    get 
    { 
     this.EnsureID(); 
     string uniqueID = this.UniqueID; 
     if ((uniqueID != null) && (uniqueID.IndexOf(this.IdSeparator) >= 0)) 
     { 
      return uniqueID.Replace(this.IdSeparator, '_'); 
     } 
     return uniqueID; 
    } 
} 

Je suppose donc que ClientID, UniqueId et ID sont nuls - même si, comme ci-dessus lecture juste les deux premières déclenchera tous être configurés. Notez également que NamingContainer n'est pas nul. Il a été mis en place. Par conséquent, la procédure à suivre est assez simple, c'est-à-dire qu'elle vérifie ctrl.ID == null et si c'est le cas, il suffit de lire ctrl.ClientID. Et c'est ce que j'ai fait parce que, dans le temps, je dois vraiment me tortiller. Mais je suis toujours intéressé par la réponse si quelqu'un le sait du haut de leurs têtes.

Pourquoi la valeur ID d'un contrôle enfant, d'un TemplateField ajouté dynamiquement, est-elle définie à une heure différente de celle des autres contrôles?

+0

Il se trouve que je suis complètement porté loin avec la mauvaise extrémité du bâton et totalement raté la réponse la plus évidente de tous. Voir la réponse acceptée. – rism

+0

Je pensais que c'était une bonne question. Au cours de mes presque 20 années de programmation, je trouve que les problèmes les plus simples semblent souvent les plus longs à résoudre. – Ruslan

+0

@Ruslan - Eh bien merci pour le laisser-aller, mais je me sens toujours un peu idiot. C'est l'une de ces périodes où la réponse est pratiquement dans la question.;) La bonne nouvelle, c'est que j'ai appris deux ou trois choses en même temps que Reflector, donc pas une perte totale. – rism

Répondre

2

Ce n'est pas qu'ils se comportent différemment, mais que presque toujours lorsque vous ajoutez un contrôle de manière déclarative, vous définissez l'ID tout de suite. Essayez d'ajouter une étiquette sans ID à une page et parcourez la collection de commande et vérifier son identité, il sera nul (assurez-vous de ne pas montrer son clientID car il obtiendrait l'ID remplie):

<asp:Label runat="server">something</asp:Label> 

Notez également que si vous l'exécutez comme ça, vous obtenez une durée sans ID.

+0

La réponse est tellement évidente que je me sens stupide 4 ayant posé la question à la 1ère place. Comment pourrais-je ne pas voir les implications de container.Controls.Add (new CheckBox()); Pour ma défense, je tiens à souligner que, en raison d'un nouveau "coup de pouce de santé", j'ai stupidement décidé d'arrêter de boire de la caféine lundi;) – rism

2

Freddy a raison.

Vous êtes responsable de la définition des ID dans la méthode InstantiateIn. Et il est logique que ClientID les génère automatiquement s'il n'est pas spécifié autrement.

Les contrôles déclaratifs obtiennent leur ID affecté par un générateur de page lors de la compilation d'une page. Si vous deviez regarder l'un des fichiers de temporaires générés dans le dossier « Temporary ASP.NET Files », vous pouvez trouver quelque chose comme ça (pragma) dénudées:

//creating a template field, where CopiledBindableTemplateBuilder is the ITemplate 
//and its InstantiateIn = @__BuildControl__control9 
@__ctrl.ItemTemplate = new System.Web.UI.CompiledBindableTemplateBuilder(
    new System.Web.UI.BuildTemplateMethod([email protected]__BuildControl__control9), 
    new System.Web.UI.ExtractTemplateValuesMethod([email protected]__ExtractValues__control9)); 

//and @__BuildControl__control9 calling @__BuildControlButton1 
private global::System.Web.UI.WebControls.Button @__BuildControlButton1() 
{ 
    global::System.Web.UI.WebControls.Button @__ctrl; 

    @__ctrl = new global::System.Web.UI.WebControls.Button(); 
    this.Button1 = @__ctrl; 
    @__ctrl.ApplyStyleSheetSkin(this); 
    @__ctrl.ID = "Button1"; //<-- here it gets an ID 
    @__ctrl.Text = "Button"; 
    return @__ctrl; 
} 
Questions connexes