views:

570

answers:

1

Hello,

I am trying to figure out how to declaratively pass in a event handler into a user control, but I am stumped. All I can make work is the user control's event handler.. I can't seem to bubble up the caught event into the parent page. Ideas would be quite welcome. Here is my code:

Default.aspx:

<%@ Page Language="VB" %>
<%@ Register TagPrefix="rpt" TagName="filter" Src="WebUserControl.ascx" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;

<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head runat="server">
    <title>Test Controls</title>
</head>
<body>
    <form id="form1" runat="server">
        <rpt:filter ID="DataView1Filters" runat="server" SelectedIndexChanged="DropDown_SelectedIndexChanged" />    
        <asp:Label ID="Label1" runat="server" />
    </form>

<script runat="server">
    Public Sub DropDown_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)
        Label1.Text = String.Format("Inside declarative event handler. {0}<br>", Label1.Text)
    End Sub
</script>

</body>
</html>

WebUserControl.ascx:

<%@ Control Language="VB" ClassName="WebUserControlTest" %>

<asp:Panel ID="TestPanel" runat="server"></asp:Panel>

<script runat="server">

Private AllEvents As New System.ComponentModel.EventHandlerList
Public Custom Event SelectedIndexChanged As EventHandler
    AddHandler(ByVal value As EventHandler)
        AllEvents.AddHandler("SelectedIndexChanged", value)
    End AddHandler

    RemoveHandler(ByVal value As EventHandler)
        AllEvents.RemoveHandler("SelectedIndexChanged", value)
    End RemoveHandler

    RaiseEvent(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim value As EventHandler = CType(AllEvents("SelectedIndexChanged"), EventHandler)
        If Not value Is Nothing Then
            value.Invoke(sender, e)                
        End If
    End RaiseEvent
End Event

Private Sub _SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)
    Dim ctrl As DropDownList = Me.FindControl("TestDropDownList")
    If Not ctrl Is Nothing Then
        Me.ViewState("ItemSelection") = ctrl.SelectedIndex
    End If
    Dim Label1 As Label = Parent.FindControl("Label1")
    Label1.Text = String.Format("Inside user control event handler. {0}<br>", Label1.Text)
    RaiseEvent SelectedIndexChanged(sender, e)
End Sub

Private Overloads Sub OnLoad(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
    Dim ctrl As New DropDownList
    With ctrl
        .ID = "TestDropDownList"
        .Items.Clear()
        .AutoPostBack = True
        AddHandler .SelectedIndexChanged, AddressOf _SelectedIndexChanged
        .Items.Add(New ListItem("-- Select --", String.Empty))
        .Items.Add(New ListItem("Item 1", "1"))
        .Items.Add(New ListItem("Item 2", "2"))
        If Not Me.ViewState("ItemSelection") Is Nothing Then
            .SelectedIndex = CInt(Me.ViewState("ItemSelection"))
        Else
            .SelectedIndex = 0
        End If
    End With
    TestPanel.Controls.Add(ctrl)
End Sub

</script>

Thanks!

+1  A: 

See this previous post:

http://stackoverflow.com/questions/943794/handling-user-control-events-on-containing-page

Edit - added based on your comment

I should have read the question more clearly.

As far as having a UserControl raise an event that the containing page can respond to, I do not believe that this can be done declaratively.

Unless my knowledge is just lacking, the only way to accomplish this is by explicitly creating an event in the control and then handling it (by coding the event handler) on the parent page, as shown in the example I linked to.

David Stratton
Sorry, either I don't follow the other posts or they don't explain my situation (especially since I don't see any HTML and declarative attributes assigning event handlers.
mycall
Thanks for the quick reply. Since I'm dynamically generating the DropDownList within the control, how could the control know what page event handler to call, without passing in the event handler. I guess I'm over my head here.
mycall