?
Solved

Add SelectedIndex row command to gridview in code

Posted on 2008-10-06
12
Medium Priority
?
3,724 Views
Last Modified: 2012-06-27
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


0
Comment
Question by:Steve Krile
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 5
12 Comments
 
LVL 13

Expert Comment

by:crazyman
ID: 22649097
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
 
LVL 16

Author Comment

by:Steve Krile
ID: 22649130
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
 
LVL 13

Expert Comment

by:crazyman
ID: 22649401
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 16

Author Comment

by:Steve Krile
ID: 22649433
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
 
LVL 16

Author Comment

by:Steve Krile
ID: 22650009
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
 
LVL 16

Author Comment

by:Steve Krile
ID: 22650814
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
 
LVL 13

Expert Comment

by:crazyman
ID: 22653032
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
 
LVL 16

Author Comment

by:Steve Krile
ID: 22653069
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
 
LVL 13

Accepted Solution

by:
crazyman earned 2000 total points
ID: 22653292
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
 
LVL 16

Author Comment

by:Steve Krile
ID: 22653328
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
 
LVL 16

Author Comment

by:Steve Krile
ID: 22653352
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
 
LVL 13

Expert Comment

by:crazyman
ID: 22653362
No probs.

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

cheers
0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

IntroductionWhile developing web applications, a single page might contain many regions and each region might contain many number of controls with the capability to perform  postback. Many times you might need to perform some action on an ASP.NET po…
The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …

718 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question