Dynamic GridView has 0 rows in RowCommand

I have a dynamically created GridView to which I attach a handler using the AddHandler command.

The problem is that when I try to reference sender.rows inside this function, it doesn't do anything because it says sender.rows.count = 0.

I've done enough dynamic form creation that I'm sure I'm creating controls by binding them and adding a handler at appropriate points during the init / load / load_complete page.

Also, I have almost the same code as on another form which is not dynamic and has access to values ​​in strings.

Considering the RowCommand event is firing, it is clear that I am clicking on the row. For some reason, this just isn't available for the handler event.

Does anyone have any ideas on how to fix this?

Background: What I really want to do is access the values ​​that are string bound. I am creating an SQLCommand and binding it to a dynamic grid and I would rather talk to the grid datasource, but that seems to be impossible. I may be missing something, but so far it seems like reading values ​​from the GridView (which I hate doing) is the only thing that works.

Thanks, Sean

Update (code):

Create dynamic view (executed on load)

sbFormHTML.AppendLine(String.Format("<tr><td colspan=""2""><asp:GridView ID=""{0}"" runat=""server"" DataKeyNames=""primary_key""><Columns>", dataElement.Attributes.GetNamedItem("name").Value))

sbFormHTML.AppendLine("<asp:BoundField DataField=""primary_key"" Visible=""False"" SortExpression=""primary_key"" />")
sbFormHTML.AppendLine("<asp:CommandField SelectText=""Edit"" ShowSelectButton=""True"" />")
sbFormHTML.AppendLine("<asp:CommandField ShowDeleteButton=""True"" />")

For Each data_item As XmlNode In dataElement.SelectSingleNode("data_items").ChildNodes

    Dim header As String = fnGetAttributeValue(data_item, "label")
    If header = "" Then header = data_item.Attributes.GetNamedItem("dbfield").Value

    sbFormHTML.AppendLine(String.Format("<asp:BoundField DataField=""{0}"" HeaderText=""{1}"" SortExpression=""{0}"">", data_item.Attributes.GetNamedItem("dbfield").Value, header))
    sbFormHTML.AppendLine("</asp:BoundField>")

Next
sbFormHTML.AppendLine("</Columns></asp:GridView>")
sbFormHTML.AppendLine(String.Format("</td></tr>"))

      

AddHandler:

'bind grid RowCommand function to all dynamic grids
Dim dynamicGrids = findWebControlsRecursive(Page, "^gvDyn")
For Each dynamicGrid As GridView In dynamicGrids
    AddHandler dynamicGrid.RowCommand, AddressOf subHandleRowCommand
    Response.Write(String.Format("{0} has {1} rows<br/>", dynamicGrid.ID, dynamicGrid.Rows.Count))
Next

      

Try to do something about it:

Protected Sub subHandleRowCommand(ByVal sender As GridView, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs)
    'skm
    If e.CommandName = "Select" Then


        Try
            Response.Write(String.Format("{0} has {1} rows<br/>", sender.ID, sender.Rows.Count))

    'Remainder of the code snipped for brevity.

End Sub

      

Set up snap to grid:

Protected Sub sbLoadGrid(ByVal gridNode As XmlNode)

    ' Databind a GridView object to its SQL query

    Dim conn As SqlConnection = New SqlConnection('connection string here')
    conn.Open()
    Dim cmd As SqlCommand = New SqlCommand("", conn)
    Dim dbTable As String = gridNode.Attributes.GetNamedItem("dbtable").Value

    cmd.CommandText = String.Format("SELECT {0}ID AS primary_key,", dbTable)
    For Each data_item As XmlNode In gridNode.SelectSingleNode("data_items").ChildNodes
        cmd.CommandText &= String.Format(" {0},", data_item.Attributes.GetNamedItem("dbfield").Value)
    Next

    cmd.CommandText = Regex.Replace(cmd.CommandText, ",$", String.Format(" FROM {0}", dbTable))

    Dim dsGrid As SqlDataReader = cmd.ExecuteReader

    Dim tempGrid As GridView = getControlReference(gridNode.Attributes.GetNamedItem("name").Value)
    tempGrid.DataSource = dsGrid
    tempGrid.AutoGenerateColumns = False

    tempGrid.DataBind()



End Sub

      

+1


a source to share


2 answers


I don't see where the sbloadgrid function gets called anywhere, but I highly recommend that you try refactoring your code to create the GridView more traditionally by setting its properties, adding it to a placeholder on the page if you need it to be dynamic.

With the query, I would recommend that you use the parameters in the command text and add them to the sql command. It can still be done dynamically and you end up opening up a lot less problems, then using regexes to bundle your queries.

This is probably not the answer you wanted, but unless you have an incredibly strong reason to keep the code as it is, I would suggest rewriting it. If you come across the number of columns you got in your request, I would even suggest setting it in the asp page instead of dynamic.



If there are several different formats that you could show, you can set them on the page and only change the data source update and enable one dynamically at runtime, leaving them disabled and hidden by default.

All of this is probably easier to maintain.

+1


a source


Since you are creating the gridview control dynamically, the ViewState is not saved and this explains why rows.count is returned as 0 in the EventHandler.



+1


a source







All Articles