2009-12-22 83 views
0

我能够动态地创建绑定列和页脚,行像这样在我的GridView:asp.net - GridView的动态尾行创建问题

protected void Page_Load(object sender, EventArgs e) 
     { 
      if (!Page.IsPostBack) 
      { 
       CreateGridView(); 
      } 
     } 

     private void CreateGridView() 
     { 
      GridView1.Columns.Clear(); 

      DataTable dataTable = Book.GetBooksDataSet().Tables[0]; 

      CommandField cf = new CommandField(); 
      cf.ShowEditButton = true; 

      GridView1.Columns.Add(cf); 

      int colCount = 1; 
      foreach (DataColumn c in dataTable.Columns) 
      { 
       BoundField boundField = new BoundField(); 

       boundField.DataField = c.ColumnName; 
       boundField.HeaderText = c.ColumnName; 
       //boundField.FooterText = "---"; 

       if (colCount == 3 || colCount == 5) 
       { 
        boundField.ReadOnly = true; 
       } 

       GridView1.Columns.Add(boundField); 
       colCount++; 
      } 

      GridView1.ShowFooter = true; 

      GridView1.DataSource = dataTable; 
      GridView1.DataBind(); 

      GridViewRow footerRow = GridView1.FooterRow; 
      Button b = new Button(); 
      b.Text = "Add New"; 
      int i = 0; 
      footerRow.Cells[i].Controls.Add(b); 
      foreach (DataColumn c in dataTable.Columns) 
      { 
       ++i; 
       TextBox tb = new TextBox(); 
       footerRow.Cells[i].Controls.Add(tb); 
      } 
     } 
.................................... 
.................................... 
.................................... 
} 

但问题是,当我点击“新增” - 按钮,它立即消失。而且,我也无法添加任何事件处理程序。或拦截其行为是这样的:

protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e) 
     { 
      int index = Convert.ToInt32(e.CommandArgument); 

      if (e.CommandName == "Edit") 
      { 
       GridView1.EditIndex = index; 

       GridViewRow selectedRow = ((GridView)e.CommandSource).Rows[index]; 

       //We can get cell data like this 
       string id = selectedRow.Cells[1].Text; 
       string isbn = selectedRow.Cells[2].Text; 

       //This is necessary to GridView to be showed up. 
       CreateGridView(); 
      } 
      else if (e.CommandName == "Update") 
      { 
       LinkButton updateButton = (LinkButton)e.CommandSource; 

       DataControlFieldCell dcfc = (DataControlFieldCell)updateButton.Parent; 

       GridViewRow gvr = (GridViewRow)dcfc.Parent; 

       //The update................... 
       //Update grid-data to database 
       UpdateDataInTheDatabase(gvr.Cells[1].Controls);     

       //Grid goes back to normal 
       GridView1.EditIndex = -1; 

       //This is necessary to GridView to be showed up. 
       CreateGridView(); 
      } 
     } 

还有一两件事,我看到了一些解决方案,提出处理GridView的rowBound事件。但我需要从Page_load事件处理程序或GridView1_RowCommand事件处理程序中执行此操作。

+0

你已经能够解决呢? – 2009-12-28 14:26:09

+0

不,我从Page_Load()中删除了(!Page.IsPostBack),但现在我在GridView1_RowCommand()的行中得到了“输入字符串格式不正确”int index = Convert.ToInt32(e .CommandArgument)。也就是说,我无法拦截“添加新”的按钮点击事件。 – anonymous 2009-12-28 16:54:22

+0

我在回复中添加了一些示例代码。希望能帮助到你。 – 2009-12-29 21:00:42

回答

1

动态创建的控件每亩为re-created on every postback。您的“添加新的”按钮会导致回发,因此动态创建的页脚会消失。是否有一个原因,这个网格必须动态创建?从你发布的代码看来,你可以用标记代替。如果不是,则必须在每次回发中重新创建动态控件。

编辑补充: 我玩了这一点,下面的工作,网格不消失和事件处理,但它实际上并没有做任何事情。希望这可以帮助。

标记:

<p><asp:Literal ID="Literal1" runat="server" /></p> 
    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" 
     OnRowCommand="GridView1_RowCommand" 
     OnRowEditing="GridView1_RowEditing"/> 

代码:

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

private DataTable GetBooksDataTable() 
{ 
    var dt = new DataTable(); 
    dt.Columns.Add("ID", typeof(int)); 
    dt.Columns.Add("Title", typeof(string)); 
    dt.Columns.Add("Author", typeof(string)); 

    for (int index = 0; index < 10; index++) 
    { 
     dt.Rows.Add(index, "Title" + index, "Author" + index); 
    } 
    return dt; 
} 

private void BindGridView() 
{ 
    var dt = GetBooksDataTable(); 

    GridView1.Columns.Clear(); 
    GridView1.ShowFooter = true; 

    var cf = new CommandField(); 
    cf.HeaderText = "Action"; 
    cf.ShowEditButton = true; 
    GridView1.Columns.Add(cf); 

    for (int index = 0; index < dt.Columns.Count; index++) 
    { 
     var boundField = new BoundField(); 
     boundField.DataField = dt.Columns[index].ColumnName; 
     boundField.HeaderText = dt.Columns[index].ColumnName; 
     GridView1.Columns.Add(boundField); 
    } 

    GridView1.DataSource = dt; 
    GridView1.DataBind(); 

    var footer = GridView1.FooterRow; 
    var b = new LinkButton(); 
    b.Text = "Add New"; 
    b.CommandName = "Add New"; 
    footer.Cells[0].Controls.Add(b); 
    for (int index = 1; index < dt.Columns.Count + 1; index++) 
    { 
     var tb = new TextBox(); 
     footer.Cells[index].Controls.Add(tb); 
    } 

} 

protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e) 
{ 
    Literal1.Text = e.CommandName; 
} 

protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e) 
{ 
    Literal1.Text = "Editing row index " + e.NewEditIndex.ToString(); 
} 
+0

该文章涉及.Net 2及以上版本,在这种构造中,在'Page_Init'上使用对象创建。 – 2009-12-24 14:36:30

+0

我不认为动态控制用法发生了变化,Page_Init始终是创建动态控件的推荐事件。关键是它们必须在每个回发站上重新创建;建议使用Init,因为ViewState在此事件后恢复。我可能是错的,我总是找到一种方法来避免动态创建控件,因为它们很难合作。 – 2009-12-24 15:17:50

1

将您的代码从Page_Load移至Page_Init。在Page_Load中添加的内容仅适用于一次回发的生命周期。

你会那么可以添加事件处理器,拦截事件等