Wrox Programmer Forums
Go Back   Wrox Programmer Forums > ASP.NET and ASP > ASP.NET 2.0 > ASP.NET 2.0 Basics
|
ASP.NET 2.0 Basics If you are new to ASP or ASP.NET programming with version 2.0, this is the forum to begin asking questions. Please also see the Visual Web Developer 2005 forum.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the ASP.NET 2.0 Basics section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old October 29th, 2007, 10:14 PM
Friend of Wrox
 
Join Date: Jul 2006
Posts: 238
Thanks: 0
Thanked 2 Times in 2 Posts
Send a message via MSN to rsearing
Default Why is addhandler for linkbutton.click not working

Ok, the big picture, is I am trying to dynamically add link buttons to a gridview that represents the people that can sign up for an event. I have a variable that represents the most amount of people that can sign up for the event--so the gridview will show ENROLL for each row that contains an empty slot.

Now--I actually got this to work--but the LAST thing I have to do--I can't seem to work--that is, tying to the ENROLL button's click event. I put a breakpoint on the handler and it never fires.

I have can't, for the life of me, figure out what I have done wrong to tie this event handler up. Here is the code. I set up the button in the GridView's RowDataBound event (which is itself bound in it's parent DataList ItemDataBound Event. The parent Datalist simply shows every event where the child Gridview shows all the members based upon the Event.


Private rowCount As Integer = 0
    Private shCount As Integer = 0
    Private random As Integer = 1

Protected Sub DataList3_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataListItemEventArgs) Handles DataList3.ItemDataBound
        Dim myGridView As GridView
        rowCount = 0
        myGridView = CType(e.Item.FindControl("GridView2"), GridView)
        AddHandler myGridView.RowDataBound, AddressOf myGridView_RowDataBound
        Dim shiftID As Integer = DataList3.DataKeys.Item(0)
        ObjectDataSource1.SelectParameters.Clear()
        ObjectDataSource1.SelectParameters.Add("shiftID", shiftID)
    End Sub


    Protected Sub myGridView_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs)
        Dim shift As String = DataList3.DataKeys.Item(shCount)

        Dim numPeople As Integer = Member.GetNumPeoplePerShift(shift)
        If (e.Row.RowType = DataControlRowType.DataRow) Then
            rowCount += 1
        ElseIf (e.Row.RowType = DataControlRowType.Footer) Then
            If rowCount < numPeople Then
                Dim tbl As New Table
                tbl = e.Row.Parent
                For i As Integer = 1 To (numPeople - rowCount)
                    Dim myRow As New GridViewRow(-1, -1, DataControlRowType.DataRow, DataControlRowState.Normal)
                    Dim myCell As New TableCell
                    Dim myLinkButton As New LinkButton
                    myLinkButton.ID = "myID" & random
                    random += 1
                    myLinkButton.Text = "Enroll"
                    AddHandler myLinkButton.Click, AddressOf enrollButton_Click
                    myCell.Controls.Add(myLinkButton)
                    myRow.Cells.Add(myCell)
                    tbl.Rows.Add(myRow)
                Next
            End If
            rowCount = 0
            shCount += 1
        End If
    End Sub

    Protected Sub enrollButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim memID As Integer = Member.GetMemberID(Membership.GetUser.UserName)
        Dim shift As String = DataList3.DataKeys.Item(shCount)
        Dim shID As Integer = DataList1.DataKeys(shift)
        'Const conString As String = "Data Source=.*****
        'Const conString As String = "Data Source=xxxxx
        Dim insertString As String = "INSERT INTO [shift_member] ([shiID], [memID]) VALUES (" & shID & ", " & memID & ")"
        Dim knightsDBConn As New SqlConnection(AppConfiguration.ConnectionString)
        Dim sqlCmd As New SqlCommand(insertString, knightsDBConn)
        sqlCmd.CommandType = CommandType.Text
        knightsDBConn.Open()
        sqlCmd.ExecuteNonQuery()
        sqlCmd = Nothing
        Response.Redirect("~/Member/checkenrollment.aspx")
    End Sub
 
Old October 29th, 2007, 11:33 PM
planoie's Avatar
Friend of Wrox
 
Join Date: Aug 2003
Posts: 5,407
Thanks: 0
Thanked 16 Times in 16 Posts
Default

Hey Rob,

You hook up the click handler when the grid row is data bound (i.e. when it's initially drawn) but it's not wired up on the next page hit when the grid is reconstructed from viewstate. Thus the handler never can fire.

What you need to do is to wire the event handler during the row created event of the grid. This happens when the grid is initially data bound as well as when it's reconstructed from viewstate so the handler wiring will exist during the postback.

One thing that might make this easier: Don't name the buttons dynamically based on the row index. Each instance of the button can be named the same because it exists in a different naming container (i.e. the button's full ID will be prefixed with the grid's row ID so they'll be unique). With buttons of the same name, you can then use the FindControl method on the row to get at the button instance.

By the looks of it (single DB insert and a redirect), you don't really need to do a postback for this so you might consider putting the button action in a whole different page and using hyperlinks instead of buttons. There's not much reason to post a large viewstate of a list/grid view just for a couple values you could put on the querystring. Sometimes the simplest approach is easiest (and very likely will perform better).

-Peter
 
Old October 30th, 2007, 08:16 AM
Friend of Wrox
 
Join Date: Jul 2006
Posts: 238
Thanks: 0
Thanked 2 Times in 2 Posts
Send a message via MSN to rsearing
Default

Peter,

Thank you for your reply. My issue is, that I had to actually create the button in the RowDataBound event - as that was the event that allowed me to tie into the parent DataList to get the current shiftID-and it allowed me to use the logic to add the linkButton.

Are you suggesting that I could have added the linkbutton on the RowCreated Event and basically copy the entire RowDataBound event into it?

Thanks,
Rob

EDIT: Peter, the only place I can actually add the row is the RowDataBaound event. Since the RowCreated Event happens prior to the DataBound--how can I use that to tie into it?
 
Old October 30th, 2007, 01:47 PM
Friend of Wrox
 
Join Date: Jul 2006
Posts: 238
Thanks: 0
Thanked 2 Times in 2 Posts
Send a message via MSN to rsearing
Default

Peter,

let me add this, when I get rid of the RowDataBound and then create a RowCreated so that it is now:

Protected Sub myGridView_RowCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs)
        Dim shift As String = DataList3.DataKeys.Item(shCount)

        Dim numPeople As Integer = Member.GetNumPeoplePerShift(shift)
        If (e.Row.RowType = DataControlRowType.DataRow) Then
            rowCount += 1
        ElseIf (e.Row.RowType = DataControlRowType.Footer) Then
            If rowCount < numPeople Then
                Dim tbl As New Table
                tbl = e.Row.Parent
                For i As Integer = 1 To (numPeople - rowCount)
                    Dim myRow As New GridViewRow(-1, -1, DataControlRowType.DataRow, DataControlRowState.Normal)
                    Dim myCell As New TableCell
                    Dim myLinkButton As New LinkButton
                    myLinkButton.ID = "myID" & random
                    random += 1
                    myLinkButton.Text = "Enroll"
                    AddHandler myLinkButton.Click, AddressOf enrollButton_Click
                    myCell.Controls.Add(myLinkButton)
                    myRow.Cells.Add(myCell)
                    tbl.Rows.Add(myRow)
                Next
            End If
            rowCount = 0
            shCount += 1
        End If
    End Sub

Then I get an error that tbl = e.row.parent is nothing. So my question becomes...how can I add a row to the gridview in the RowCreated event?

Regards,
Rob

(another thing I thought you might have meant was leaving the RowDataBound function but capturing the eventhandler of the button in the RowCreated event that might have been triggered when I manually add the row--this doesn't work--basically, a RowCreated event never is triggered for the rows I manually created)
 
Old October 31st, 2007, 02:29 PM
planoie's Avatar
Friend of Wrox
 
Join Date: Aug 2003
Posts: 5,407
Thanks: 0
Thanked 16 Times in 16 Posts
Default

To your last point: You aren't really adding a row from the perspective of the gridview, you're just adding display elements (which happen to be table rows).

Getting this type of thing to work can be quite tricky as you are finding out. Adding controls programmatically causes lots of problems.

You haven't responded to my explanation about why the button's click event is not handled. It's important to understand the 'why' of this problem in order to understand how to fix it. My main point is that you need to recreate the object structure in order for the click handlers to function properly. By default with a control that is reconstructed from viewstate you aren't getting your custom buttons. You might actually be able to solve this problem by simply rebinding the gridview. If this is done in the right place, you will wire up the custom buttons the same as the previous page hit, but this time there will be a postback event for the page to process and ultimately for the button to handle.

-Peter
 
Old October 31st, 2007, 05:37 PM
Friend of Wrox
 
Join Date: Jul 2006
Posts: 238
Thanks: 0
Thanked 2 Times in 2 Posts
Send a message via MSN to rsearing
Default

Thank you very much....you are right about one thing--this is VERY confusing.

My only question is in regards to where to databind the GridView? Remember, the GridView is nested in the DataList. It appears the only place I can even reference the GridView is in the DataList3_ItemDataBound method..as everyother place I try results in "Nothing" as a return value.

Sigh.....I have tried researching the heck out of this.

:)
Rob

 
Old October 31st, 2007, 09:32 PM
planoie's Avatar
Friend of Wrox
 
Join Date: Aug 2003
Posts: 5,407
Thanks: 0
Thanked 16 Times in 16 Posts
Default

You'll need to rebind the whole datalist.

-Peter
 
Old November 12th, 2007, 06:06 PM
toy toy is offline
Registered User
 
Join Date: Nov 2007
Posts: 1
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via AIM to toy
Default

hey peter
thanks for some really great insight
ive been tearing my hair out for the past few days trying to get this to work
i still havent tamed it
so thats why im posting here

i found that when i added my buttons during the OnRowCreated event
it didnt add
but when i tried to do it during OnRowDataBound i had partial success
(ie, controls got added but additional child controls were not)
could you explain this?
and the discrepancy with your row created suggestion?






Similar Threads
Thread Thread Starter Forum Replies Last Post
Input button click event not working Scott Rider General .NET 3 August 13th, 2005 12:20 PM
dynamic linkbutton disappear when click it logoin2 ASP.NET 1.0 and 1.1 Basics 0 December 2nd, 2004 02:39 PM
Beware the AddHandler etoostr General .NET 0 November 6th, 2004 05:53 PM
AddHandler from String jbrenn@friends.edu Pro VB.NET 2002/2003 2 July 6th, 2003 04:18 PM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.