2012-10-01 1 views
2

Fondamentalement, je veux un bouton qui ajoute une nouvelle colonne avec mes contrôles (c'est-à-dire TextBox, DropDownList) à mon GridView.Comment ajouter TemplateField créé dans le balisage .aspx à la colonne GridView dans le code derrière?

semble déjà assez simple avec ceci:

protected void btn_AddColumn_Click(object sender, EventArgs e) 
{ 
    TemplateField MyTemplateField = new TemplateField(); 
    gv_SupplierPrices.Columns.Add(MyTemplateField); 
} 

que je veux ajouter ce balisage:

<asp:TemplateField> 
    <ItemTemplate> 
     <table style="width:100%;"> 
      <tr> 
      <td><asp:TextBox ID="tbox_ItemPrice" runat="server"></asp:TextBox></td> 
      </tr> 
     </table> 
    </ItemTemplate> 
</asp:TemplateField> 

est ici le problème. Comment puis-je utiliser un TemplateField que j'ai créé dans le balisage sur ma page .aspx et l'ajouter à ma nouvelle colonne sur le code derrière? Je ne sais pas et je ne veux pas créer mon TemplateField sur le code parce que je ne serai pas capable de créer des balisages élaborés ou de fantaisie. Ils vont juste ressembler à des contrôles qui sont les uns à côté des autres. C'est très moche.

P.S. Si quelqu'un est curieux de savoir ce que je suis en train de faire, je transforme mon GridView en une feuille de calcul Excel. Les nouvelles colonnes représentent un fournisseur et chaque ligne représente un article que le fournisseur vend. Ils le veulent parce qu'il est plus facile de comparer les prix côte à côte pendant qu'ils le remplissent.


Mise à jour: je l'ai déjà compris. Je peux simplement appeler la colonne de mon GridView de codebehind qui représente le TemplateField que j'ai créé dans le balisage, puis je l'ajoute.

<asp:GridView ID="gv_SupplierTable" runat="server" AutoGenerateColumns="False" 
         DataKeyNames="Id" DataSourceID="TestTable_DS"> 
         <Columns> 
          <asp:BoundField DataField="Id" HeaderText="Id" InsertVisible="False" 
           ReadOnly="True" SortExpression="Id" /> 
          <asp:BoundField DataField="AccountType" HeaderText="AccountType" 
           SortExpression="AccountType" /> 
          <asp:TemplateField AccessibleHeaderText="MyTemplateFieldCreated in Markup"> 
           <ItemTemplate> 
            <table style="width:100%;"> 
             <tr> 
              <td><asp:TextBox ID="tbox_ItemPrice" runat="server"></asp:TextBox></td> 
             </tr> 
            </table> 
           </ItemTemplate> 
          </asp:TemplateField> 
         </Columns> 
        </asp:GridView> 

Puis, en codebehind, je peux accéder à cette colonne qui représente le TemplateField créé dans le balisage et l'ajouter à nouveau sur le clic de bouton, comme une nouvelle copie:

protected void btn_AddColumn_Click(object sender, EventArgs e) 
    { 
    DataControlField newColumn = this.gv_SupplierTable.Columns[2]; 
           //this column at index #2 from my GridView represents     
           the TemplateField created in markup since the columns 
           at index #0 and index #1 are DataBound. 
    gv_SupplierTable.Columns.Add(newColumn); 
    } 

Répondre

1

Vous pouvez activer ou désactiver la visibilité chaque colonne.

gv_SupplierPrices.Columns[10].Visible = true; 
+0

Croyez-le ou non, c'est l'approche WAY SIMPLER. Précuisez toutes les colonnes et lignes dont vous avez besoin et cachez-les au moment de la conception. Ensuite, libérez-les au besoin de votre codebehind, et je suggère à l'intérieur de l'événement databound() – Fandango68

1

Dans votre position, je considérerais mordre la balle et étudier la création de champs basés sur des modèles par programmation. Ce serait une nuisance, mais une fois que vous auriez terminé, vous auriez fini. Bien sûr, vous voudriez les abstraire dans une classe d'aide ou un contrôle séparé.

0

Voici des exemples de couple sur l'ajout dynamiquement une colonne à votre GridView:

protected void Page_Init(object sender, EventArgs e) 
{ 
    btnAddColumn.Click += new EventHandler(btnAddColumn_Click); 

    BoundField temp = new BoundField(); 
    temp.DataField = "Source"; 
    temp.HeaderText = "Source"; 
    temp.SortExpression = "Source"; 

    gv.Columns.Add(temp); 
} 

void btnAddColumn_Click(object sender, EventArgs e) 
{ 
    TemplateField temp = new TemplateField(); 
    temp.HeaderText = txtNewColumn.Text; 

    txtNewColumn.Text = string.Empty; 

    gv.Columns.Add(temp); 
} 

ASPX:

<div> 
    <asp:TextBox ID="txtNewColumn" runat="server" /> 
    <asp:Button ID="btnAddColumn" runat="server" Text="Add Column" /> 
</div> 
<asp:GridView ID="gv" 
    runat="server" 
    AutoGenerateColumns="False" 
    DataSourceID="dsExceptions"> 
    <Columns> 
     <asp:BoundField DataField="Message" HeaderText="Message" /> 
    </Columns> 
</asp:GridView> 

<asp:ObjectDataSource ID="dsExceptions" 
    runat="server" 
    SelectMethod="GetExceptions" 
    TypeName="WebApplication.Data.MyDataContext" EnablePaging="True" 
    SelectCountMethod="GetExceptionCount" > 
    <SelectParameters> 
     <asp:Parameter Name="maximumRows" Type="Int32" /> 
     <asp:Parameter Name="startPageIndex" Type="Int32" /> 
     <asp:Parameter Name="startRowIndex" Type="Int32" /> 
    </SelectParameters> 
</asp:ObjectDataSource> 

Mon ObjectDataSource ne fait que commencer une collection de Exceptions je crée, de sorte que vous pouvez ignorer cette partie du code.

Donc j'ajoute une colonne via le code dans le gestionnaire Page_Init, ainsi que d'ajouter une colonne avec le texte d'en-tête défini au texte dans txtNewColumn. Une chose à ce sujet, cependant, est que si vous actualisez la page, il perdra les colonnes que vous avez ajoutées avec le bouton sur la page. Vous devez ajouter du code dans le gestionnaire d'événements de clic de bouton pour stocker les nouvelles colonnes. Elles sont donc toujours dans le GridView lors du rechargement. Comme il semble que les colonnes représentent un fournisseur, vous pouvez simplement ajouter un formulaire pour que quelqu'un ajoute un fournisseur à votre système. Le fournisseur est enregistré dans une base de données/datastore quelque part, et dans le Page_Init, vous obtenez tous les fournisseurs de cette banque de données et boucle sur eux, en créant les champs de modèle pour les fournisseurs.Ce serait quelque chose comme ceci:

// I am just creating a list here, you would pull the vendor names in from the 
// datastore here instead. 
var vendors = new List<string> { "Vendor A", "Vendor B", "Vendor C" }; 
foreach (var vendor in vendors) 
{ 
    TemplateField temp = new TemplateField(); 
    temp.HeaderText = vendor; 
    gv.Columns.Add(temp); 
} 
+0

Oui. Une colonne représente un fournisseur/fournisseur et la toute première colonne (la plus à gauche) est le SEUL champ lié. Chaque cellule de la première colonne représente un article et l'utilisateur doit spécifier les prix des fournisseurs par article. c'est-à-dire Dell Desktop: Fournisseur A - 499 $/ch. Vendeur B - 479 $/ch. Fournisseur C - 510 $/ch. Je dois être en mesure d'ajouter autant de fournisseurs (en colonnes) que possible. J'apprécie la réponse. Mais cela ne me donne toujours pas une idée de comment obtenir le TemplateField que j'ai créé dans le balisage et l'ajouter à ma colonne à partir du codebehind. Je ne sais pas et ne veux pas créer les contrôles ASP par programme. – SymphonyX7

+0

J'ai montré exactement comment créer les colonnes dynamiquement, je ne sais pas quoi d'autre vous avez besoin. Pour faire ce que vous devez faire, ce sera la manière la plus simple. – Gromer

+1

Vous avez montré comment ajouter des colonnes dynamiquement. Je l'ai déjà fait dans mon post avec deux lignes de code. Ce que je cherche est d'utiliser le TemplateField que j'ai créé dans MARKUP, pas CODEBEHIND, et l'ajouter dynamiquement à la GridView en tant que nouvelles colonnes. Ce que vous avez posté est encore en train de créer les DataControlFields dans codebehind, pas de balisage. – SymphonyX7

Questions connexes