mycall
mycall

Reputation: 11

Declarative event handling from ASP.NET user control to page

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

<html xmlns="http://www.w3.org/1999/xhtml">
<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!

Upvotes: 1

Views: 2868

Answers (2)

Andy
Andy

Reputation: 778

I was recently having this same issue in C#. When you set up an event called SelectedIndexChanged asp.net will bind the attribute OnSelectedIndexChanged when using the declarative syntax.

So if you change

<rpt:filter ID="DataView1Filters" runat="server" SelectedIndexChanged="DropDown_SelectedIndexChanged" />  

To

<rpt:filter ID="DataView1Filters" runat="server" OnSelectedIndexChanged="DropDown_SelectedIndexChanged" />  

It should work.

Upvotes: 0

David
David

Reputation: 73564

See this previous post:

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.

Upvotes: 1

Related Questions