我有一个动态创建的GridView,我正在使用AddHandler命令附加一个处理程序。
问题在于,当我尝试在该函数中引用sender.rows时,它不会执行任何操作,因为它表示sender.rows.count = 0.。
我已经完成了足够的动态表单创建,我非常确定我正在创建控件,绑定它们,并在页面init / load / load_complete期间在适当的位置添加处理程序。
另外,我在另一个非动态的表单上几乎完全相同的代码隐藏,并且它能够访问行中的值。
考虑到RowCommand事件正在触发,很明显我点击了一行。由于某种原因,它不在处理程序事件的范围内。
有没有人对如何解决这个问题有任何想法?
背景:我真正想要做的是访问数据绑定到行的值。我正在创建一个SQLCommand并将其绑定到动态网格,我更愿意与网格的数据源进行对话,但这似乎不可能。也许我错过了一些东西,但是现在似乎从GridView中读取值(我讨厌做的)是唯一可行的。
谢谢, 肖恩
更新(代码):
创建动态视图(在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
尝试用它做点什么:
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
数据绑定网格:
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
答案 0 :(得分:1)
由于您正在动态创建gridview控件,因此ViewState不会持久化,这可以解释为什么rows.count在EventHandler中返回为0。
答案 1 :(得分:1)
我没有看到sbloadgrid函数在哪里被调用,但我强烈建议你尝试将代码重构为更传统的GridView创建,设置它的属性,如果你将它添加到页面上的占位符需要它是动态的。
通过查询,我建议您在命令文本中使用参数并将它们添加到sql命令中。它仍然可以动态完成,从长远来看,您可以使用正则表达式构建查询,从而减少问题。
这可能不是你想要的答案,但除非你有一个令人难以置信的强大理由保持代码的方式,我建议重写它。如果您在查询中获得的列数已经预先知道,我甚至建议您在asp页面中设置它而不是动态。
如果您可以显示几种不同的格式,则可以在页面上设置每种格式,只更改数据源并在运行时动态启用其中一种,默认情况下禁用和隐藏它们。 / p>
所有这些都可能更容易维护。