从ASP.NET用户控件到页面的声明性事件处理

时间:2009-09-30 02:53:06

标签: asp.net vb.net events user-controls controls

我试图弄清楚如何以声明方式将事件处理程序传入 一个用户控件,但我很难过。我能做的就是用户控件 事件处理程序..我似乎无法将捕获的事件冒泡到父级中 页。想法非常受欢迎。这是我的代码:

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>

谢谢!

2 个答案:

答案 0 :(得分:1)

见上一篇文章:

Handling User Control Events on Containing Page

编辑 - 根据您的评论添加

我应该更清楚地阅读这个问题。

至于让UserControl引发包含页面可以响应的事件,我不相信这可以声明性地完成。

除非我的知识缺乏,否则实现此目的的唯一方法是在控件中显式创建一个事件,然后在父页面上处理它(通过编码事件处理程序),如我链接到的示例所示。

答案 1 :(得分:0)

我最近在C#中遇到了同样的问题。当您设置名为SelectedIndexChanged的事件时,asp.net将在使用声明性语法时绑定属性OnSelectedIndexChanged

所以如果你改变了

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

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

它应该有用。