Answered by:
Gridview Nested in Repeater-Postback problem

Question
-
User646364117 posted
When a button is clicked in a gridview row, in the GridView RowCommand the repeater is bound.
When I am debugging in the Repeater ItemDataBound, after the button was clicked the variable 'blocktype' is empty which is causing my problem
Here is my Markup. I have omitted some irrelevant columns
<asp:Repeater ID="rptBlock_Tab2" runat="server" > <ItemTemplate> <asp:Label ID="Label1" runat="server" Text="Block: " Style="font-weight: bold; color: white; background-color: #3366ff;" /> <asp:Label ID="lblBlockName" runat="server" Text='<%# Eval("blockname") %>' Style="font-weight: bold; color: white; background-color: #3366ff; padding-left: 3px; padding-right: 3px;" /> <asp:Label ID="lblBlockType" runat="server" Text='<%# Eval("blocktype") %>'></asp:Label> <asp:HiddenField ID="hfBlockID" runat="server" Value='<%# Eval("id") %>'></asp:HiddenField> <asp:GridView ID="gvContent2" AutoGenerateColumns="false" runat="server" OnRowCommand="gvContent2_RowCommand" OnRowDataBound="gvContent2_RowDataBound" ShowFooter="False" > <Columns> <asp:TemplateField HeaderText="Short Text" HeaderStyle-Width="300px"> <ItemTemplate> <asp:Label ID="lbl_shorttext" runat="server" Text='<%#Eval("shorttext") %>'></asp:Label> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView> <asp:Button ID="btnUse" runat="server" Text="Use" /> </ItemTemplate> </asp:Repeater>
Here is the gridview rowCommand
The repeater is bound toward the end, indicated in bold
Protected Sub gvContent2_RowCommand(sender As Object, e As GridViewCommandEventArgs) 'For Tab 2 Dim gv As GridView = CType(sender, GridView) If e.CommandName = "PopulatePlaceholders" Then Dim row As GridViewRow = CType(((CType(e.CommandSource, Control)).NamingContainer), GridViewRow) Dim inputText As String = ftb1.Text 'Add spaces so split won't fail inputText = " " & inputText & " " Dim outputText As String = "" Dim textArray() As String Dim hfBlockName As HiddenField = TryCast(row.FindControl("hfBlockName"), HiddenField) Dim blockName As String = hfBlockName.Value.ToString() Dim hfBlockType As HiddenField = TryCast(row.FindControl("hfBlockType"), HiddenField) Dim blockType As String = hfBlockType.Value.ToString() Dim lbl_shorttext As Label = TryCast(row.FindControl("lbl_shorttext"), Label) Dim shortText As String = lbl_shorttext.Text.ToString() Dim lbl_longtext As Label = TryCast(row.FindControl("lbl_longtext"), Label) Dim longText As String = lbl_longtext.Text.ToString() Dim chkIncluded As CheckBox = TryCast(row.FindControl("chkIncluded"), CheckBox) Dim included As Boolean = chkIncluded.Checked textArray = Split(inputText, "{ " & blockName & " }") If InStr(inputText, blockName) > 0 Then 'tests that correct button pressed Select Case blockType Case "Short Text" outputText = textArray(0) & shortText & textArray(1) Case "Long Text" outputText = textArray(0) & longText & textArray(1) Case "Single Select" outputText = "" Case "Multi Select" outputText = "" Case Else End Select ftb1.Text = Trim(outputText) 'Delete Block and rebind rptBlock_Tab2 Dim BlockId As Integer = Convert.ToInt16(e.CommandArgument) 'Dictionary is cleared in Populate_RptBlock_Tab2 Dim EmbeddedBlocksDictionary As Dictionary(Of String, Integer) = CType(Session("DictEmbeddedBlocks"), Dictionary(Of String, Integer)) If EmbeddedBlocksDictionary.ContainsKey(blockName) = False Then EmbeddedBlocksDictionary.Add(blockName, BlockId) 'This is the block name and id of the item that was clicked on Dim dt1 As DataTable = New DataTable() Dim sqlConn As SqlConnection = New SqlConnection(ConfigurationManager.ConnectionStrings("DB_A54278_steve48ConnectionString").ConnectionString) Dim query1 As String = "SELECT Name as BlockName,blocktype.blocktype As BlockType,block.id From block Join blocktype On block.blocktype_id =blocktype.id Join block_template ON block.id=block_template.block_id WHERE block_template.template_id = @templateid ORDER BY typeorder" Dim cmd1 As SqlCommand = New SqlCommand(query1, sqlConn) Dim da1 As SqlDataAdapter = New SqlDataAdapter(cmd1) 'Try cmd1.Parameters.AddWithValue("@templateid", Session("ActiveTemplateID")) dt1.Columns.Add("BlockName", GetType(String)) dt1.Columns.Add("id", GetType(Integer)) dt1.Columns.Add("BlockType", GetType(String)) sqlConn.Open() Dim rdr As SqlDataReader = cmd1.ExecuteReader() While rdr.Read If EmbeddedBlocksDictionary.ContainsKey(rdr("BlockName").ToString()) = False Then 'If Then block Is Not In the dictionary it can be added To dt1 To be displayed 'Any block previously clicked on is in the dictionary dt1.Rows.Add(rdr("BlockName").ToString(), Convert.ToInt16(rdr("id").ToString)) End If End While rdr.Close() Dim numrows As Integer = dt1.Rows.Count sqlConn.Close() rptBlock_Tab2.DataSource = dt1 rptBlock_Tab2.DataBind() Session("DictEmbeddedBlocks") = EmbeddedBlocksDictionary 'Catch ex As Exception 'End Try End If End If End If End Sub
And here is the repeater ItenDataBound command, This is where the variable block type is empty after the gridview button is clicked.
Private Sub rptBlock_Tab2_ItemDataBound(sender As Object, e As RepeaterItemEventArgs) Handles rptBlock_Tab2.ItemDataBound If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then Dim hf As HiddenField = CType(e.Item.FindControl("hfBlockID"), HiddenField) Dim blockId As Integer blockId = Convert.ToInt16(hf.Value) Dim blocktype As String Dim lbl1 As Label = CType(e.Item.FindControl("lblBlockType"), Label) blocktype = lbl1.Text.ToString Dim gv As GridView = CType(e.Item.FindControl("gvContent2"), GridView) gv.DataSource = EMailGen3.GridviewContent.GetAllGridViewContents(blockId) gv.DataBind() Select Case blocktype Case "Short Text", "Single Select", "Multi Select" gv.Columns(1).Visible = False Case "Long Text" 'Do Nothing Case Else End Select gv.DataBind() Dim btn As Button = CType(e.Item.FindControl("btnUse"), Button) If blocktype <> "Multi Select" Then btn.Visible = False End If End If End Sub
Monday, February 17, 2020 11:16 PM
Answers
-
User-1330468790 posted
Hi, sg48asp,
I have tried your code and I think generally your code is correct.
You can rebind the data to repeater in the rowcommand event of the gridview control. Then the event "ItemDatabound" of the Repeater control should be triggered after data binding completed in each item.
Thus, you should have found the label "lblBlockType" with data assigned.
Here what I can suggest is to check the values in runtime:
- Set the break point in the line "rptBlock_Tab2.DataSource = dt1" of RowCommand event and check the data in "dt1" to see if the blocktype is null or not. (In case there is something wrong in database stuff)
- Check the value of lbl1.Text.Tostring. In case you have set the break point on the line of blocktype while it has not assigned with value yet. While it moves to next line, it shows the value. See below comparison.
Comparison:
In the line,
Move to the next line,
Best regards,
Sean
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, February 18, 2020 8:50 AM
All replies
-
User-1330468790 posted
Hi, sg48asp,
I have tried your code and I think generally your code is correct.
You can rebind the data to repeater in the rowcommand event of the gridview control. Then the event "ItemDatabound" of the Repeater control should be triggered after data binding completed in each item.
Thus, you should have found the label "lblBlockType" with data assigned.
Here what I can suggest is to check the values in runtime:
- Set the break point in the line "rptBlock_Tab2.DataSource = dt1" of RowCommand event and check the data in "dt1" to see if the blocktype is null or not. (In case there is something wrong in database stuff)
- Check the value of lbl1.Text.Tostring. In case you have set the break point on the line of blocktype while it has not assigned with value yet. While it moves to next line, it shows the value. See below comparison.
Comparison:
In the line,
Move to the next line,
Best regards,
Sean
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, February 18, 2020 8:50 AM -
User646364117 posted
hi Sean,
Thank you for your response and taking the time to see what I was trying to do. After reading your response, I looked at my code again and saw that when I was rebuilind the datatable dt1 I forgot to add the blocktype column. see bold text below
When I put it in, that fixed my problem.
Dim cmd1 As SqlCommand = New SqlCommand(query1, sqlConn) Dim da1 As SqlDataAdapter = New SqlDataAdapter(cmd1) 'Try cmd1.Parameters.AddWithValue("@templateid", Session("ActiveTemplateID")) dt1.Columns.Add("BlockName", GetType(String)) dt1.Columns.Add("id", GetType(Integer)) dt1.Columns.Add("BlockType", GetType(String)) sqlConn.Open() Dim rdr As SqlDataReader = cmd1.ExecuteReader() While rdr.Read If EmbeddedBlocksDictionary.ContainsKey(rdr("BlockName").ToString()) = False Then 'If Then block Is Not In the dictionary it can be added To dt1 To be displayed 'Any block previously clicked on is in the dictionary dt1.Rows.Add(rdr("BlockName").ToString(), Convert.ToInt16(rdr("id").ToString), rdr("BlockType").ToString()) End If End While
Tuesday, February 18, 2020 12:56 PM