2010-12-14 58 views
1

Comment ajouter un contrôle d'étiquette supplémentaire dynamiquement (ne doit être ajouté que sous certaines conditions). Je suis en train de faire quelque chose comme ceci:Ajouter dynamiquement un contrôle d'étiquette supplémentaire à un élément <ItemTemplate>

<asp:DataGrid id="dg" runat="server" AutoGenerateColumns="false"> 
<Columns> 
    <asp:TemplateColumn SortExpression="Column1"> 
     <HeaderTemplate> 
     <asp:LinkButton Runat="server" text="Column1 Hdr" ID="col1Hdr"> 
     </asp:LinkButton> 
     </HeaderTemplate> 
     <ItemTemplate> 
     <asp:Label ID="col1Label" runat="server" Text='<%# Method1(DataBinder.Eval(Container.DataItem, "Column1").ToString(), DataBinder.Eval(Container.DataItem, "Column2").ToString()) %>' >   
      <asp:PlaceHolder ID="col2Holder" runat="server"></asp:PlaceHolder> 
     </asp:Label> 
     </ItemTemplate>  
    </asp:TemplateColumn> 
</Columns> 
</asp:DataGrid> 

Sinon, j'essayé de mettre l'espace réservé dans un modèle séparé:

<EditItemTemplate> 
     <asp:PlaceHolder ID="col2Holder" runat="server"></asp:PlaceHolder> 
    </EditItemTemplate> 

mais en vain. Des astuces sur la façon de créer l'espace réservé seulement dans certains cas (comme pour certaines valeurs de Colonne1/Colonne2), plutôt que d'opter pour une approche répéteur ... Je reçois une exception de référence nulle mais cela a été résolu quand j'ai dû mentionner explicitement:

protected PlaceHolder col2Holder = new Placeholder(); 

au lieu de

protected PlaceHolder col2Holder; 

Mais si method1 est en mesure de régler correctement la valeur de texte de la « Column1, il ne fait rien pour la valeur du Colonne2 ... y at-il quelque chose que je suis manquant ou existe-t-il une manière différente de faire ceci?

est ici le defn de method1:

public string Method1(string col1, string col2) 
{ 
    col1 += "Called method1"; 
    Label col2label= new Label(); 

    col2label.Visible = true; 
    col2label.Text = col2;   

    col2Holder.Controls.Add(col2label); 
    col2Holder.DataBind(); 

return col1; 

}

+0

Je recommande fortement de ne pas utiliser DataBinder.Eval - son lent et mal. Mieux vaut lancer le bon type et obtenir les données directement. Quoi lancer dépend bien sûr de votre DataSource mais disons que c'est un IEnumerable de DataRows, alors vous devez écrire ((DataRow) Container.DataItem) ["Column1"] au lieu de DataBinder.Eval (Container.DataItem, "Column1") –

+1

la raison pour laquelle vous ne pouvez pas déclarer une variable nommée col2Holder sur le niveau de classe et attendez qu'elle contienne une référence à l'espace réservé dans votre ItemTemplate est qu'il y aura N nombre de ItemTemplates contenant chacun leur espace réservé unique. –

+0

alors quel est un bon moyen de résoudre ce problème?J'ai besoin que le soit généré seulement dans certains cas, pas toujours. Merci! –

Répondre

1

Où et quand avez-vous besoin de contrôle supplémentaire à insérer?

Vous devriez très probablement connecter une méthode à l'événement OnItemDataBound et y décider si vous souhaitez ajouter ou non un contrôle. L'événement vous donne une référence à l'élément étant lié de sorte que vous pouvez dire e.Item.Controls.Add(your_control)

Mise à jour

Ah, maintenant je comprends ce que vous demandez. Vous devez ajouter un autre argument à votre Method1 qui prend un DataGridItem. Lorsque vous appelez Method1, vous l'ajoutez comme ceci Method1(Container)Container fait référence au DataGridItem en question. Ensuite, vous pouvez dire dans le Method1

public string Method1(DataGridItem item) 
{ 
    string col1 = DataBinder.Eval(item.DataItem, "Column1").ToString(); 
    string col2 = DataBinder.Eval(item.DataItem, "Column2").ToString(); 

    var col2label = new Label() { Visible = true, Text = col2 }; 
    var col2Holder = item.FindControl("col2Holder"); 

    col2Holder.Controls.Add(col2label); 

    return col1 + "Called method1"; 
} 

BTW, vous ne pouvez pas ajouter des contrôles à une étiquette, votre ItemTemplate devrait ressembler à ceci

<ItemTemplate> 
    <asp:Label ID="col1Label" runat="server" Text="<%# Method1(Container) %>" /> 
    <asp:PlaceHolder ID="col2Holder" runat="server" /> 
</ItemTemplate> 

Si vous voulez que la nouvelle étiquette à l'intérieur imbriquée la première étiquette, vous devriez faire cela explicite dans la méthode, et laisser l'espace réservé:

<ItemTemplate> 
    <asp:Label ID="label" runat="server" Text="<%# Method1(Container) %>" /> 
</ItemTemplate> 

public string Method1(DataGridItem item) 
{ 
    string col1 = DataBinder.Eval(item.DataItem, "Column1").ToString(); 
    string col2 = DataBinder.Eval(item.DataItem, "Column2").ToString(); 

    var label = item.FindControl("label"); 
    var col2label = new Label() { Visible = true, Text = col2 }; 

    col1Holder.Controls.Add(col2label); 

    return col1 + "Called method1"; 
} 
+0

Je souhaite que le contrôle supplémentaire soit inséré dans l'élément , peut être un div ou un span. Doit être inséré en vérifiant non seulement les valeurs de Column1 = "something" mais aussi les valeurs de Column2! = Null .... à titre d'exemple ... c'est-à-dire en passant à la fois les valeurs de la base de données et en ajoutant le nouveau contrôle. –

+0

mis à jour ma réponse avec une exampe de comment vous pouvez passer une référence à l'ItemTemplate dans votre méthode afin que vous puissiez ajouter de nouveaux contrôles. –

+0

quand vous dites que vous voulez dire le correct? Penser comment cette méthode pourrait être appelée maintenant .. en utilisant un Id ou quelque chose? –