Add SelectedIndex row command to gridview in code

I have the following code in the RowDataBound event of a GridView.  The purpose is to look at the ID of the row, and if there are details in my db with that ID, draw a new GridView.  I want to be able to click on an edit button from this detail grid and do stuff.  Everything in the code below "works".  I now need some direction on how to bind the click/SelectedValueChanged event of these dynamically created Grids.  There could be one, two, or twenty of these detail grids.

Protected Sub RequirementView_RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs) Handles RequirementView.RowDataBound
.
.{other unrelated stuff}
.
            Dim crid As Int64 = Convert.ToInt64(DataBinder.Eval(e.Row.DataItem, "CRRequirementID"))
            If Not (IsNothing(crid)) Then
                Dim ds As New DataSet
                Dim cr As New CoreRequirement
                Try
                    ds = cr.GetSubRequirements("", 0, -1, Convert.ToInt64(crid), 0)
                    If ds.Tables(0).Rows.Count > 0 Then
                        Dim dg As New GridView
                        dg.AutoGenerateColumns = False
                        dg.ShowHeader = False
                        dg.CssClass = "SubReqBox_on"
                        Dim dgc As BoundField = New BoundField()
                        dgc.DataField = "CRSubRequirement"
                        dgc.HtmlEncode = False
                        dgc.InsertVisible = True
                        dgc.ItemStyle.Width = "490"
                        dgc.ItemStyle.Wrap = True

                        dg.Columns.Add(dgc)

                        Dim dgbtn As ButtonField = New ButtonField()
                        dgbtn.ItemStyle.Width = "60"
                        dgbtn.ButtonType = ButtonType.Link
                        dgbtn.ControlStyle.CssClass = "linkbutton"
                        dgbtn.ItemStyle.HorizontalAlign = HorizontalAlign.Center
                        dgbtn.Text = "Edit"
                        dgbtn.CommandName = "Select"

                        dg.Columns.Add(dgbtn)
                        dg.DataSource = ds
                        dg.DataBind()
                        Dim lt As Literal = New Literal()
                        lt.Text = "<br/><br/>"
                        e.Row.Cells(1).Controls.Add(lt)
                        e.Row.Cells(1).Controls.Add(dg)
                    End If
                Catch ex As Exception

                End Try


            End If
end sub


LVL 16
Steve KrileAsked:
Who is Participating?
 
crazymanConnect With a Mentor Commented:
Yes but this
<a class="linkbutton" href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$RequirementView$ctl04$ctl02','Select$0')">Edit</a>

means
"find me a control with the id 'ctl00$ContentPlaceHolder1$RequirementView$ctl04$ctl02'
and raise the default event with the argument 'Select$0'.

You do not now have a control with that id, hence you will get no event.
You will get NO events raised if the controls are not re-added, it doesnt matter if you dont want to see them or not, they dont exist so any postback will be ignored completely.

If you just want 'stuff' to happen you could always use a hyperlink and pass some args along the querystring....
0
 
crazymanCommented:
If your using c# .NET 2.0 you can use an anonymous delegate

ie :

dg.ItemCommand = delegate(object sender,EventArgs e)
{
}

in vb

AddHandler dg.RowCommand, AddressOf eventName
0
 
Steve KrileAuthor Commented:
Yeah.  So, I tried that.  Now I'm looking at my code, there may be another important factor!  

The Parent GridView is in an UpdatePanel.  I've added the code you suggest above, put a break point on the eventName sub, and it never gets hit.

.
.
.
                        dg.CssClass = "SubReqBox_on"
                        AddHandler dg.RowCommand, AddressOf SubReqSelected '<------ added line
                        Dim dgc As BoundField = New BoundField()
                        dgc.DataField = "CRSubRequirement"
                        dgc.HtmlEncode = False
                        dgc.InsertVisible = True
.
.
.

Here is the little sub.  I put the break point on Dim i as Int16 = 1, and it never stops.  The click does cause all the contents of my grid to disappear.  The grid remains, but all the rows are blank.

    Public Sub SubReqSelected(ByVal sender As Object, ByVal e As GridViewCommandEventArgs)
        Dim i As Int16 = 1
    End Sub

0
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

 
crazymanCommented:
Problem is, when you dynamically add controls you need to make sure they are re-added EVERY postback.
If your grid uses viewstate and doesnt re-bind to the datasource then the RowDataBound event wont fire which in turn wont creeate the controls

You could try in Page_Load putting somethin like

if (Page.IsCallBack)
{
mygrid.DataBind();
}

presuming you are using SqlDataSource or ObjectDataSource ?
0
 
Steve KrileAuthor Commented:
OK, but that's not the problem.  Having a blank grid doesn't bother me, because the click of the sub-grid's button is going to be handled and stuff will be done.  I mentioned the blank grid just to confirm that indeed there is a button and indeed it is triggering a post back.   Right now, that sub-grid click doesn't do anything (other than posting back of course)...even with the AddHandler code you suggested.  
0
 
Steve KrileAuthor Commented:
I've been looking at the code generated and the Edit buttons on the embedded select buttons looks like this:

<a class="linkbutton" href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$RequirementView$ctl04$ctl02','Select$0')">Edit</a>

So, they are definately getting some sort of post-back event attached to them.  But, again, I can't correlate this __doPostBack on my server-side code.
0
 
Steve KrileAuthor Commented:
Um....yeah, this is getting ugly.  I kind of bailed on this approach and am going with a more Client-side tact.  Still, the code-behind is required, but I'm going to put two hidden fields on my designer page, populate them with an OnClientClick event, and watch for their values on Postback in the Page_load event....SHEESH!  That's a lot of hoops.

Here are the relavent bits.

While adding a GridView dynamically to a cell of another grid, I add a Handler for the RowDataBound event:

                        Dim dg As New GridView
                        dg.AutoGenerateColumns = False
                        dg.ShowHeader = False
                        dg.CssClass = "SubReqBox_on"
                        dg.ID = "sub_" & crid.ToString
                        AddHandler dg.RowDataBound, AddressOf SubReqDataBind <--this will fire when the row is databound, and that is where I will handle adding a button and setting up the clientclick event

The "cell" that will hold my button is empty before databinding:

                        Dim dgbtn As TemplateField = New TemplateField()
                        dgbtn.ItemStyle.Width = "60"
                        dgbtn.ItemStyle.HorizontalAlign = HorizontalAlign.Center

Here is the sub that handls the Databound event of this new dynamically-added gridview:

    Public Sub SubReqDataBind(ByVal sender As Object, ByVal e As GridViewRowEventArgs)
        If e.Row.RowType = DataControlRowType.DataRow Then
            Dim crid As Int64 = Convert.ToInt64(DataBinder.Eval(e.Row.DataItem, "CRRequirementID"))
            Dim scrid As Int64 = Convert.ToInt64(DataBinder.Eval(e.Row.DataItem, "CRSubRequirementID"))
            Dim btn As New LinkButton
            btn.Text = "Edit"
            btn.CssClass = "linkbutton"
            btn.OnClientClick = "subreq('" & crid & "','" & scrid & "');"

            e.Row.Cells(1).Controls.Add(btn)
        End If
    End Sub


Then, there is the Javascript and hidden fields on the Designer page:
    <asp:HiddenField ID="crid" runat="server" />
    <asp:HiddenField ID="scrid" runat="server" />
    <script language="javascript" type="text/javascript">
        function subreq(crid,scrid)
        {
            alert(crid + ', ' + scrid);
            var cridBx = document.getElementById('<%=crid.ClientID %>');
            var scridBx = document.getElementById('<%=scrid.ClientID %>');
            cridBx.value = crid;
            scridBx.value = scrid;
           
        }
    </script>

FInally, there is the code to handle the occasion where both these hidden fields have values:

If IsPostBack
            If crid.Value.Length > 0 And scrid.Value.Length > 0 Then
                Session("CRRequirementID") = crid.Value
                Session("CRSubRequirementID") = scrid.Value
                Session("CR_EditType") = 2
                Response.Redirect("CoreRequirement_DetailEdit.aspx")
            End If
End If



Yeah, all this is ugly and is only required because I can't seem to work out how to create a button in a gridview dynamically that triggers a public sub on the page.


0
 
crazymanCommented:
You wont get the events fired because the sub grid was not re-added.
If the controls are not re-added then how can an event be fired for a control that does not exist in the control tree.
This is a common mistake when creating dynamic controls and i have answered quite a few similar questions on this subject

see
http://www.experts-exchange.com/Programming/Languages/.NET/ASP.NET/Q_23219395.html
http://www.singingeels.com/Articles/Dynamically_Created_Controls_in_ASPNET.aspx

0
 
Steve KrileAuthor Commented:
Um...well, the buttons are not needed for a postback.  Am I missing something here.  The sub-grid is being drawn the first time the page is created and I need the buttons right then.  If any of the buttons are clicked, I want stuff to happen - namely, read the ID of the selected grid row and redirect the user.  So, I am not seeing this sub grid in a post back - but I don't care.
0
 
Steve KrileAuthor Commented:
Right...which is essentially what I'm doing.  But rather than using a querystring which has ID's exposed, I'm sending the info to hidden boxes, submitting the form, and doing stuff from there.

Thanks for your help thought.
0
 
Steve KrileAuthor Commented:
So, what you are saying, just for posterity, is that I am rightly building these things the first time my page is loaded, then the click event is acting properly....however, when the page posts back, controls with those names are no longer available - thus the postback event has no meaning.

I think I got it.  
0
 
crazymanCommented:
No probs.

Did you read the singing eels article, it really is worth reading if you get a spare 15 mins.

cheers
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.