Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Nested Gridview event not firing

Status
Not open for further replies.

byurow

Programmer
Jul 7, 2002
111
US
Let me first start with...I am teaching myself .net :) Now, having said that...I have a page that contains a 3-level nested gridview:

parent
child
grandchild


For the most part..it works. The parent and child grids both work perfectly. The grandchild however, is causing some issues. I am able to add a record and delete a record from the grandchild grid but I cannot enter edit mode. While stepping through the code, I have determined that the DataBind methods are not actually calling the RowDataBound event. They are not erroring out, not being skipped, just not going anywhere. While stepping through the code, I go to that line, then immediately go to the next line instead of going to the RowDataBound event. I have no idea why! Part of my code is below...if you need more let me know. I appreciate any help you can offer!

Code:
    Protected Sub gvTask_RowEditing(ByVal sender As Object, ByVal e As GridViewEditEventArgs)
        Dim gvTemp3 As GridView = DirectCast(sender, GridView)
        gvUniqueID1 = gvTemp3.UniqueID
        gvEditIndex1 = e.NewEditIndex
        gvDirective.DataBind()
    End Sub

Code:
    Protected Sub gvDirective_RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs) Handles gvDirective.RowDataBound

        Dim row As GridViewRow = e.Row
        Dim strSort As String = String.Empty

        'Check if this is our Blank Row being databound, if so make the row invisible 
        If e.Row.RowType = DataControlRowType.DataRow Then
            If DirectCast(e.Row.DataItem, DataRowView)("Directive_No").ToString() = "0" Then
                e.Row.Visible = False
            End If
        End If

        ' Make sure we aren't in header/footer rows 
        If row.DataItem Is Nothing Then
            Exit Sub
        End If

        'Find Child GridView control 
        Dim gv3 As New GridView()
        gv3 = DirectCast(row.FindControl("gvTask"), GridView)

        'Check if any additional conditions (Paging, Sorting, Editing, etc) to be applied on child GridView 
        If gv3.UniqueID = gvUniqueID Then
            gv3.PageIndex = gvNewPageIndex
            gv3.EditIndex = gvEditIndex
            'Check if Sorting used 
            If gvSortExpr1 <> String.Empty Then
                GetSortDirection()
                strSort = " ORDER BY " & String.Format("{0} {1}", gvSortExpr1, gvSortDir)
            End If
            'Expand the Child grid 
            ClientScript.RegisterStartupScript([GetType](), "Expand", "<SCRIPT LANGUAGE='javascript'>expandcollapse2('div" & DirectCast(e.Row.DataItem, DataRowView)("Directive_ID").ToString() & "','one');</script>")
        End If

        'Prepare the query for Child GridView by passing the Directive_ID of the parent row 

        gv3.DataSource = ChildDataSource2(DirectCast(e.Row.DataItem, DataRowView)("Directive_No").ToString(), strSort)
        gv3.DataBind()

    End Sub

I am also declaring the following global variables:

Private gvUniqueID As String = [String].Empty
Private gvNewPageIndex As Integer = 0
Private gvEditIndex As Integer = -1
Private gvSortExpr As String = [String].Empty
Private gvUniqueID1 As String = [String].Empty
Private gvNewPageIndex1 As Integer = 0
Private gvEditIndex1 As Integer = -1
Private gvSortExpr1 As String = [String].Empty
Private RecurringEventRecordNo As Integer = 0
'Public WithEvents gvDirective As UserControl
Dim WithEvents gvDirective As New GridView
Dim WithEvents gvTask As New GridView


Any idea why the code works in the parent and child but not the grandchild gridview? Thanks!


Brenda
 
some insights:
1. Avoid global variables. You have no need for them.
2. I question the need for 3 nested tables. There is most likely a better way to handle the scenario.
3. Use a 3rd party js library (jquery) to handle the javascript. don't embed the js into the code behind.
4. Inline editing creates complexity in the code behind that is not needed. I would separate the viewing and editing into a separate pages. This also opens up the possibility of ajax and modal editing windows if you don't want to navigate away from the grid. If you go this route, use a Repeater to generate your html instead of a GridView. I have found the GridViews are more trouble then they are worth and I get much more control over html from a Repeater.

I would guess the issue with the grandchild events not firing is due to how the events are wired. it's been awhile since I messed with webforms, but my guess is you have problems with
postback, when you databind and which events you are handling.

RowDataBind only fires if DataBind() is called. RowCreated is fired each time a row of a gridview is rendered.
Created != Bound

Jason Meckley
Programmer
Specialty Bakers, Inc.
 
I don't see where you are setting a datasource to gvDirective before you call gvDirective.DataBind()
.

Is gvDirective the grandchild grid?
 
Thank you both for your responses. I got as far as I did through google searches...I basically found others doing the same thing and made it work for me :) (only it really doesn't work).

I didn't want to do a 3 layer grid but my users want to be able to see all data on one screen. I wanted them to filter the parent data via a drop down list then only have a parent / child grid but was told that wasn't good enough...argggg! I also tried pop-up forms but they didn't like that either. If you have a different idea...I'm all ears!

JMeckley:

1. Ok, I will fix that.
2. See above...arggg!
3. This is part of my .aspx file. I am only calling it in the code behind.

Code:
    function expandcollapse2(obj,row)
    {
        var div = document.getElementById(obj);
        var img = document.getElementById('img' + obj);
        
        if (div.style.display == "none")
        {
            div.style.display = "block";
            if (row == 'alt')
            {
                img.src = "minus.gif";
            }
            else
            {
                img.src = "minus.gif";
            }
            img.alt = "Close to view other Tasks";
        }
        else
        {
            div.style.display = "none";
            if (row == 'alt')
            {
                img.src = "plus.gif";
            }
            else
            {
                img.src = "plus.gif";
            }
            img.alt = "Expand to show Task details";
        }
    } 
    </script>

4. I will have to do some google searches on Repeaters. I don't know how to use them but will certainly give it a shot.

jbenson001:

gvDirective is the child grid where gvTask is the grandchild. The following is the code I am using to populate the datasource for the grandchild:

Code:
    Private Function ChildDataSource2(ByVal strDirective_No As String, ByVal strSort As String) As SqlDataSource
        Dim strQRY2 As String = ""
        Dim dbSrc2 As New SqlDataSource()
        dbSrc2.ConnectionString = ConfigurationManager.ConnectionStrings("SO_Compliance_DBConnectionString").ConnectionString
        strQRY2 = "SELECT Tbl_Task.Directive_No, Tbl_Task.Task_ID, Tbl_Task.Action_No, Tbl_Task.Action_Details, Tbl_Task.Suspense_Date, Tbl_Task.Total_Assets_Affected, Tbl_Task.Assets_In_Compliance, Tbl_Task.Status_Compliant, Tbl_Task.LastUpdateBy, Tbl_Task.LastUpdateDate FROM Tbl_Task" & " WHERE Tbl_Task.Directive_No = '" & strDirective_No & "'" & "UNION ALL " & "SELECT '" & strDirective_No & "','','','','','','','','','' FROM Tbl_Task WHERE Tbl_Task.Directive_No = '" & strDirective_No & "'" & "HAVING COUNT(*)=0 " & strSort

        dbSrc2.SelectCommand = strQRY2
        Return dbSrc2
    End Function

Thanks again!





Brenda
 
Where is the code you expect to run for the grandchild grid? You are binding gv3 which is a copy of gvtask. You need to write a RowDataBound event handler for gv3.
 
Here is the code for the gvTask

Code:
    Protected Sub gvTask_RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs) Handles gvTask.RowDataBound

        Dim row As GridViewRow = e.Row
        Dim strSort As String = String.Empty

        'Check if this is our Blank Row being databound, if so make the row invisible 
        If e.Row.RowType = DataControlRowType.DataRow Then
            If DirectCast(e.Row.DataItem, DataRowView)("Task_ID").ToString() = "0" Then
                e.Row.Visible = False
            End If
        End If

        ' Make sure we aren't in header/footer rows 
        If row.DataItem Is Nothing Then
            Exit Sub
        End If

    End Sub

Then it should go to the aspx file and grandchild EditItemTemplate. The first part of it is below...the missing is just extra fields:

Code:
                                                 <asp:TemplateField>
	<ItemTemplate>
        	<tr>
                <td colspan="100%">
                <div id="div<%# Eval("Directive_No") %>" style="display: none; position: relative;
                left: 15px; overflow: auto; width: 97%">
		<asp:GridView ID="gvTask" AllowPaging="True" AllowSorting="true" BackColor="#fcd494"
                	Font-Size="8pt" AutoGenerateColumns="false" Font-Names="Arial" runat="server" DataKeyNames="Directive_No" 
                	ShowFooter="true" OnPageIndexChanging="gvTask_PageIndexChanging" OnRowUpdating="gvTask_RowUpdating" 
                	OnRowCommand="gvTask_RowCommand" OnRowEditing="gvTask_RowEditing" OnRowUpdated="gvTask_RowUpdated" 
                	OnRowCancelingEdit="gvTask_CancelingEdit" OnRowDataBound="gvTask_RowDataBound" OnRowDeleting="gvTask_RowDeleting"
                	OnRowDeleted="gvTask_RowDeleted" OnSorting="gvTask_Sorting" BorderStyle="Solid" BorderWidth="2px"
                	BorderColor="#fcd494" PageSize="15" SkinID="BlueGV" Width="1000px">
                <RowStyle BackColor="#fef3e0" />
                <AlternatingRowStyle BackColor="White" />
                <HeaderStyle BackColor="#fcd494" ForeColor="Black" />
                <FooterStyle BackColor="White" />
                <Columns>
                <asp:TemplateField HeaderText="Task_ID" SortExpression="Task_ID" Visible="False">
                <ItemTemplate>
                	<asp:Label ID="lblTask_ID" Text='<%# Eval("Task_ID") %>' runat="server"></asp:Label>
                </ItemTemplate>
                <EditItemTemplate>
                	<asp:Label ID="lblTask_ID" Text='<%# Eval("Task_ID") %>' runat="server"></asp:Label>
                </EditItemTemplate>
                </asp:TemplateField>

The problem is...the code is never making it to the gvDirective RowDataBound. So all of the above is obviously not being called either. This whole process works beautifully between the parent gridview and the child...just not between the child and grandchild.

Brenda
 
I am getting confused. The orginal problem is that the child gv (gvDirective) RowDataBound event is not being called?
If that is the case, then again I ask the same question, where are yout setting a datasoruce for gvDiective in gvDirective?

HOw about naming the grids:
Which is the Parent
Which is the Child
Which is the GrandChild

Where is the original problem ocurring and what event?
 
I think I'm confused too ;)

Parent: gvComplianceType
Child: gvDirective
Grandchild: gvTask

I created a word document with screen prints of the grids to hopefully show what I am trying to do and where I am. Unfortunately, I can't upload it!

Lets try this: If I click on the edit button of the grandchild grid (gvTask) then all of the grids collapse and I never enter edit mode. When I click the edit button on the gvTask grid and step through the following code:
Code:
Protected Sub gvTask_RowEditing(ByVal sender As Object, ByVal e As GridViewEditEventArgs)
        Dim gvTemp3 As GridView = DirectCast(sender, GridView)
        gvUniqueID1 = gvTemp3.UniqueID
        gvEditIndex1 = e.NewEditIndex
        gvDirective.DataBind()
End Sub
I am able to walk through without any error. However, when I get to the gvDirective.Databind() line instead of being sent to the gvDirective.OnDataBound event, it goes right to the End Sub line. When I click the edit button on the gvDirective grid and walk through the following code:
Code:
Protected Sub gvDirective_RowEditing(ByVal sender As Object, ByVal e As GridViewEditEventArgs)
        Dim gvTemp2 As GridView = DirectCast(sender, GridView)
        gvUniqueID = gvTemp2.UniqueID
        gvEditIndex = e.NewEditIndex
        GVComplianceType.DataBind()
End Sub
I get to the gvComplianceType.Databind() line and I get sent to the gvComplianceType.OnDataBound event. I am trying to determine why the exact same code works for the gvDirective grid, but not for the gvTask grid. I must be missing something but can’t figure out what! Does this help clear things up any?

Please bear with me...I'm a DBA, not a programmer :) I'm just in one of those shops where if you prove you can learn and do things correctly, they expect you to do everything!


Brenda
 
If you are in the gvTask RowEditing event, why are you trying to bind the gvDirective grid? You need to bind the gvTask grid, after setting the editIndex, so that the row show in edit mode.
 
I thought the same thing...but it doesn't work either. I need to go to the gvDirective.OnDataBound event to set up the data source and pass the ID of that grid to the gvTask grid.

It should follow the following route:

1. gvTask_RowEditing (calls gvDirective.DataBind())
2. gvDirective_RowDataBound (calls gv3.DataSource = ChildDataSource2(DirectCast(e.Row.DataItem, DataRowView)("Directive_No").ToString(), strSort))
3. ChildDataSource2
4. Goes back to gvDirective_RowDataBound (calls gvTask.DataBind())
5. gvTask_RowDataBound
6. then fills in the EditItemTemplates on the gvTask gridview in the aspx file.

Again, the process works great between the parent and child grids, just not from the child to grandchild grids. I never get to step 2. ARGGGGG

Brenda
 
Sorry, I am completely lost now, I am not sure why are you doing any of this the way that you are.
 
Ok...I really appreciate your help. I'll figure something out...even if I have to start over!

Thanks again!

Brenda
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top