2009-12-09 6 views
1

J'ai un GridView qui inclut des éléments BoundField et TemplateField. Certains des éléments TemplateField sont générés dynamiquement. Par souci de référence, voici le GridView que j'utiliseASP.NET - Problème avec GridView avec des colonnes dynamiques

<asp:GridView ID="myGridView" runat="server" AutoGenerateColumns="False" 
     DataKeyNames="ID" ShowFooter="True" EnableModelValidation="True" 
     OnLoad="myGridView_Load" OnRowCommand="myGridView_RowCommand" 
     OnRowEditing="myGridView_RowEditing" OnRowDeleting="myGridView_RowDeleting" 
     OnRowCancelingEdit="myGridView_RowCancelingEdit" 
     OnRowUpdating="myGridView_RowUpdating"> 
     <Columns> 
     <asp:BoundField DataField="Number" Visible="true" HeaderText="Test" /> 
     <asp:TemplateField HeaderText="Number"> 
      <EditItemTemplate> 
      <asp:TextBox ID="tb1" runat="server" Text='<%# Bind("Number") %>' /> 
      </EditItemTemplate> 
      <ItemTemplate> 
      <asp:Label ID="lb1" runat="server" Text='<%# Bind("Number") %>' /> 
      </ItemTemplate> 
      <FooterTemplate> 
      <asp:TextBox ID="ftb" runat="server" Text="[x]" /> 
      </FooterTemplate> 
     </asp:TemplateField> 

     <%-- Dynamically Generated Columns Will Be Inserted Here --%> 

     <asp:TemplateField HeaderText="Actions"> 
      <EditItemTemplate> 
      <asp:LinkButton ID="ulb" runat="server" Text="update" CommandName="Update" /> 
      <asp:LinkButton ID="clb" runat="server" Text="cancel" CommandName="Cancel" /> 
      </EditItemTemplate> 
      <FooterTemplate> 
      <asp:LinkButton ID="slb" runat="server" Text="insert" 
       OnClick="saveLinkButton_Click" /> 
      </FooterTemplate> 
      <ItemTemplate> 
      <asp:LinkButton ID="elb" runat="server" Text="edit" CommandName="Edit" /> 
      <asp:LinkButton ID="dlb" runat="server" Text="delete" CommandName="Delete" /> 
      </ItemTemplate> 
     </asp:TemplateField 
    </Columns>                              
     <EmptyDataTemplate> 
     <table border="0" cellpadding="0" cellspacing="0"> 
      <tr><td>Number</td></tr> 
      <tr> 
      <td><asp:TextBox ID="ntb" runat="server" /></td> 
      <td><asp:LinkButton ID="slb2" runat="server" Text="save" OnClick="saveLinkButton_Click" /></td> 
      </tr> 
     </table> 
     </EmptyDataTemplate>                     
    </asp:GridView> 

Lorsque le GridView charge au départ, tout est correctement chargé. Cependant, chaque fois que j'effectue une commande (modifier, insérer, supprimer), toutes les données disparaissent. Bizarrement, les valeurs de BoundField apparaissent toujours correctement. Cependant, tout TemplateField ne semble pas être rendu. Le code que je me sers pour travailler avec ce GridView est ici:

public partial class GridView : System.Web.UI.Page 
{ 
    private List<string> dynamicColumnNames = new List<string>(); 

    protected void Page_Load(object sender, EventArgs e) 
    { 
     LoadPageData(); 
    } 

    protected void saveLinkButton_Click(object sender, EventArgs e) 
    { 
    } 

    protected void myGridView_Load(object sender, EventArgs e) 
    { 
     if (Page.IsPostBack == false) 
     { 
      BindGridData(); 
     } 
    } 

    protected void myGridView_RowCommand(object sender, GridViewCommandEventArgs e) 
    { } 

    protected void myGridView_RowEditing(object sender, GridViewEditEventArgs e) 
    { 
     myGridView.EditIndex = e.NewEditIndex; 
     BindGridData(); 
    } 

    protected void myGridView_RowDeleting(object sender, GridViewDeleteEventArgs e) 
    { 
     LoadPageData(); 
     BindGridData(); 
    } 

    protected void myGridView_RowCancelingEdit(object sender, EventArgs e) 
    { 
     myGridView.EditIndex = -1; 
     BindGridData(); 
    } 

    protected void myGridView_RowUpdating(object sender, GridViewUpdateEventArgs e) 
    { 
     myGridView.EditIndex = -1; 
     LoadPageData(); 
     BindGridData(); 
    } 

    private void BindGridData() 
    { 
     // Create a temporary data source 
     DataTable tempData = new DataTable(); 
     tempData.Columns.Add("ID"); 
     tempData.Columns.Add("Number");   

     // Dynamically add template columns 
     foreach (string columnName in dynamicColumnNames) 
     { 
      tempData.Columns.Add(columnName); 

      TemplateField templateField = new TemplateField(); 
      templateField.HeaderTemplate = new MyTemplateField(ListItemType.Header, columnName); 
      templateField.ItemTemplate = new MyTemplateField(ListItemType.Item, columnName); 
      templateField.EditItemTemplate = new MyTemplateField(ListItemType.EditItem, columnName); 
      templateField.FooterTemplate = new MyTemplateField(ListItemType.Footer, columnName); 
      myGridView.Columns.Insert(2, templateField); 
     } 

     // Add some phony data 
     Random random = new Random(DateTime.Now.Millisecond); 
     for (int i = 0; i < 10; i++) 
     { 
      DataRow tempRow = tempData.NewRow(); 
      tempRow["Number"] = (i + 1); 

      foreach (string column in dynamicColumnNames) 
       tempRow[column] = random.NextDouble(); 
      tempData.Rows.Add(tempRow); 
     } 

     // Bind the data to the grid 
     myGridView.DataSource = tempData; 
     myGridView.DataBind(); 
    } 

    private void LoadPageData() 
    { 
     dynamicColumnNames.Add("USA"); 
     dynamicColumnNames.Add("Japan"); 
     dynamicColumnNames.Add("Mexico"); 
    } 
} 

internal class MyTemplateField : ITemplate 
{ 
    // The type of the list item 
    private ListItemType listItemType; 

    // The value to use during instantiation 
    private string value1 = string.Empty; 

    public MyTemplateField(ListItemType listItemType, string value1) 
    { 
     this.listItemType = listItemType; 
     this.value1 = value1; 
    } 

    public void InstantiateIn(Control container) 
    { 
     if (listItemType == ListItemType.Item) 
     { 
      TextBox textBox = new TextBox(); 
      textBox.ReadOnly = true; 
      textBox.DataBinding += new EventHandler(textBox_DataBinding); 
      container.Controls.Add(textBox); 
     } 
     else if (listItemType == ListItemType.EditItem) 
     { 
      TextBox textBox = new TextBox(); 
      textBox.DataBinding += new EventHandler(textBox_DataBinding); 
      container.Controls.Add(textBox); 
     } 
     else if (listItemType == ListItemType.Header) 
     { 
      Literal literal = new Literal(); 
      literal.Text = value1; 
      container.Controls.Add(literal); 
     } 
     else if (listItemType == ListItemType.Footer) 
     { 
      TextBox textBox = new TextBox(); 
      container.Controls.Add(textBox); 
     } 
    } 

    private void textBox_DataBinding(object sender, EventArgs e) 
    { 
     TextBox textBox = (TextBox)(sender); 
     GridViewRow row = (GridViewRow)(textBox.NamingContainer); 

     textBox.Text = DataBinder.Eval(row.DataItem, value1).ToString(); 
    } 
} 

Comment puis-je utiliser les commandes dans un GridView avec Dynamiquement ajouté colonnes? Quel est le problème avec mon code?

Merci!

Répondre

0

Les contrôles ajoutés dynamiquement doivent être ajoutés sur chaque publication, vous ne pouvez pas simplement ajouter ces contrôles sur le premier chargement de page. Essayez de supprimer votre BindGridData() à partir du Page.IsPostBack == false.

+0

Je pensais la même chose. Malheureusement, cela provoque simplement l'exécution de la clause ListItemType.Item. Cependant, la clause ListItemType.EditItem n'est pas exécutée. Pour cette raison, cette solution proposée ne résout pas le problème. Merci d'avoir commenté cependant. – user208662

+0

Existe-t-il un meilleur moyen de remplir dynamiquement des colonnes de modèle dans gridview? – venkat

Questions connexes