Вопрос

The datagrid reads from several xml files, so I create the columns dynamically, and added a templatefield as the last column.

A link button is added in the templatefield using RowDataBound.

Private Sub GridItem_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridItem.RowDataBound
    Try
        If e.Row.RowType = DataControlRowType.DataRow Then
            Dim linkb As New LinkButton
            linkb.Text = "Delete"
            linkb.ID = "LinkDeleteItem"
            linkb.OnClientClick = "javascript:DeleteItem('" & Convert.ToString(e.Row.RowIndex) & "')"
            e.Row.Cells(GridItem.Columns.Count - 1).Controls.Add(linkb)
        End If
    Catch ex As Exception
        lblMessage.Text = ex.Message
    End Try
End Sub

Everything works fine.

But when I click a button outside the gridview, to open a window to add a new item to the grid, the linkbuttons disappear. But the column is still there.

If I just close the new window without saving a new data (which will prompt the grid to rebind), the column remains empty. I had to reload the gridview for the linkbuttons to appear.

Is it because the linkbuttons are created on rowdatabound? How should I solve this?

Это было полезно?

Решение

This is happening because the OnRowDataBound event of GridView is NOT called on next postback. This happens because by default viewstate of GridView is set true i.e. EnableViewState property of Gridview is true. When ViewState is on, Gridview stores data from the same and OnRowDataBound event is not called. Also, at this point View state will not be applied for your linkButtons as they aren't created in page_load.

Try setting EnableViewState property to false for your gridview:

<asp:GridView ID="CustomersGridView" 
     OnRowDataBound="CustomersGridView_RowDataBound"
     EnableViewState="false"
  ....  />

OR you can also bind your GridView in page_Load as:

protected void Page_Load(object sender, EventArgs e)
    {
       CustomersGrIdView.DataBind();
    }

Now after every postback your OnRowDataBound event will be called and hence the LinkButtons will be available everytime.


NOTE: Setting EnableViewState property to false for gridview can be a bad practice to an extent, especially in scenarios of heavy data usages. Same goes for Binding gridview every time.

When using dynamic controls, they exist only until the next postback.ASP.NET will not re-create a dynamically added control. If you need to re-create a control next time too on postback, you should perform the control creation in the PageLoad event handler.

This will give you benefit of using view state with your dynamic control. Even though view state is normally restored before the Page.Load event, if you create a control in the handler for the PageLoad event, ASP.NET will apply any view state information that it has after the PageLoad event handler ends.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top