2009-12-22 2 views
0

Я могу создать BoundFields и нижнего колонтитула строки динамически, как это в моей 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); 
      } 
     } 
.................................... 
.................................... 
.................................... 
} 

Но проблема в том, когда я нажимаю на «Add New» - кнопка, она мгновенно исчезает. И также я не могу добавить к нему никакого обработчика событий. Или перехватить его действия, как это:

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

Еще одна вещь, я видел некоторые решения, которые предлагает обрабатывать rowBound событие в GridView в. Но мне нужно сделать это с помощью обработчика события Page_load или в, GridView1_RowCommand обработчика событий.

+0

Вы были в состоянии решить эту проблему? –

+0

Нет. Я удалил if (! Page.IsPostBack) из Page_Load(), но теперь я получаю «строка ввода не в правильном формате» в GridView1_RowCommand() в строке, int index = Convert.ToInt32 (e .CommandArgument). То есть, я не могу перехватить событие нажатия кнопки для «Добавить новое». – anonymous

+0

Я добавил несколько примеров кода в свой ответ. Надеюсь, поможет. –

ответ

1

Динамически созданные элементы управления re-created on every postback быть муз. Кнопка «Добавить новый» вызывает обратную передачу, поэтому динамически созданный нижний колонтитул исчезает. Есть ли причина, по которой эта сетка должна создаваться динамически? Из кода, который вы опубликовали, кажется, что вы можете сделать это в разметке. Если нет, вам нужно будет повторно создать динамические элементы управления при каждой обратной передаче.

Отредактировано для добавления: Я немного поиграл с этим, а ниже работает то, что сетка не исчезает, а события обрабатываются, но на самом деле ничего не происходит. Надеюсь это поможет.

Markup:

<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 1.1, в .Net 2 и выше, использует создание объекта на странице Page_Init' для таких конструкций. –

+0

Я не думаю, что использование динамического управления изменилось, и Page_Init всегда было рекомендуемым событием для создания динамических элементов управления. Ключевым моментом является то, что их нужно воссоздавать на каждом PostBack; Рекомендуется Init, потому что ViewState восстанавливается после этого события. Возможно, я ошибаюсь, я всегда нашел способ обойтись без динамического создания элементов управления, потому что с ними так сложно работать. –

1

Переведите код с Page_Load по номеру Page_Init. Вещи, добавленные в Page_Load, сохраняются только для жизненного цикла одной обратной передачи.

Вы бы затем иметь возможность добавлять eventhandlers, перехватывать события и т.д.

Смежные вопросы