Tuesday 8 February 2011

Capture Page Event in Web User Control

This post is about how to raise an event in an ASP.NET page and capture or handle the event in a web user control.

Today I was tasked with developing a web application that would load and daisy-chain a user-defined selection of ASP.NET forms and, at the end of the cycle, command each form to update its respective data source. The approach that I took was to create each form as a web user control that contained a form view control bound to a declarative data source for its select, insert and update operations.

This was easy enough but I still needed a way to command each form to update its data source and the options appeared to be either to create a public method in each of the user controls and call that in the page (which didn't feel like good design) or to create an event handler for the user control and use that in the page. The caveat with the second method is that event bubbling starts at the bottom (the user control) and travels up to the top level (the page) – this is groovy if you want to handle a user control event in the parent page – I needed however to raise an event in the parent page and then have each user control respond automatically to the event by saving its data.

To achieve this I used a custom base page class in ASP.Net that inherited from page and included a new 'ButtonClick' event that I could later raise in my main application page:

Imports Microsoft.VisualBasic

Namespace Custom

    Namespace Web

        Namespace UI

            Public Class Page

                Inherits System.Web.UI.Page

                Protected Sub OnButtonClick(ByVal e As EventArgs)
                    RaiseEvent ButtonClick(Me, e)
                End Sub

                Public Event ButtonClick As EventHandler

            End Class

        End Namespace

    End Namespace

End Namespace

Then in my application page I swapped out the System.Web.UI.Page inheritance with my Custom.Web.UI.Page reference and captured a button click that would raise the event:

Partial Class MyForms

    Inherits Custom.Web.UI.Page

    Protected Sub SaveButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles SaveButton.Click
        ' Raise event
        OnButtonClick(e)
    End Sub

    ' ...

End Class

Following on from this I hooked up an event handler in each of the web user controls to listen for the event and save the form's data:

Partial Class Controls_EspnForm
    Inherits System.Web.UI.UserControl

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Dim p As Custom.Web.UI.Page = CType(Page, Custom.Web.UI.Page)

        AddHandler p.ButtonClick, AddressOf Page_ButtonClick

    End Sub

    Protected Sub Page_ButtonClick(ByVal sender As Object, ByVal e As System.EventArgs)

        ' Do something here...

    End Sub

End Class

There we have it, now I could fire the insert and update commands (or execute any other code) on each and every web user control by simply firing my new 'ButtonClick' event.

Creating a custom event type and adding an argument


To send along an argument with the event simply create a custom event type (I added it to my Custom.Web.UI namespace):

Namespace Custom

    Namespace Web

        Namespace UI

            Public Class CustomEventArgs

                Inherits EventArgs

                Public EventArgument As String

                Public Sub New(ByVal arg As String)
                    Me.EventArgument = arg
                End Sub

            End Class

' ...

Raise the event along with the argument:

Partial Class MyForms

    Inherits Custom.Web.UI.Page

    Protected Sub SaveButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles SaveButton.Click

        Dim arg As Custom.Web.UI.CustomEventArgs = New Custom.Web.UI.CustomEventArgs("My Argument")

        ' Raise event
        OnButtonClick(arg)

    End Sub

    ' ...

End Class

Then just read off the argument in the Page_ButtonClick method:

Protected Sub Page_ButtonClick(ByVal sender As Object, ByVal e As System.EventArgs)

    Dim args As Custom.Web.UI.CustomEventArgs = CType(e, Custom.Web.UI.CustomEventArgs)

    Dim value As String = args.EventArgument

End Sub

1 comment:

  1. Hi,Once the design specifications have been decided, it is best to start planning the navigation structure in Web Design Cochin and content of the Web pages.Thanks....

    ReplyDelete