locked
Gridview Nested in Repeater-Postback problem RRS feed

  • 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