2009-12-09 102 views
1

我有一个包含BoundField和TemplateField元素的GridView。一些TemplateField元素是动态生成的。为了参考起见,这里要说的是,我使用ASP.NET - 动态列GridView的问题

<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> 

GridView控件当GridView控件最初加载,一切正常加载。但是,只要我执行一个命令(编辑,插入,删除),所有的数据都会消失。奇怪的是,BoundField值仍然正确显示。但是,任何TemplateField似乎都不会呈现。我使用这个GridView控件工作的代码是在这里:

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(); 
    } 
} 

如何使用命令在GridView与动态添加列?我的代码有什么问题?

谢谢!

回答

0

必须在每篇文章中添加动态添加的控件,您不能只在第一页加载时添加这些控件。尝试从Page.IsPostBack == false中删除您的BindGridData()

+0

我以为同样的事情。不幸的是,这只是导致ListItemType.Item子句被执行。但是,ListItemType.EditItem子句不会被执行。因此,这个建议的解决方案不能解决问题。不过谢谢你的评论。 – user208662 2009-12-09 23:10:50

+0

是否有更好的方式来动态填充gridview中的模板列 – venkat 2011-12-29 07:12:21