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
a source to share
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.
a source to share