Solved

Add SelectedIndex row command to gridview in code

Posted on 2008-10-06
12
3,678 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
  • 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
 
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
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 
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 500 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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

It’s quite interesting for me as I worked with Excel using vb.net for some time. Here are some topics which I know want to share with others whom this might help. First of all if you are working with Excel then you need to Download the Following …
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

762 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

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now