2010-06-24 64 views
0

我创建了一个名为Activity的Web用户控件。我已经在该用户控件OnActivityDelete上定义了一个面向公众的事件。活动控件中有一个删除按钮。当点击删除按钮时,活动控件触发OnActivityDelete事件。我在中继器中使用此Web用户控件。我将事件处理程序分配给中继器的项目数据绑定事件上的OnActivityDelete事件。当我点击活动控件的删除按钮时,事件从活动控件中触发,但它从不碰到使用该控件的页面中的事件处理程序。 (我已经用调试器进入代码并确认了这种行为)。ASP .NET Web用户控件事件

我的怀疑是,这种行为与事件处理程序添加在代码后面,当我将中继器绑定到数据源时,我只在页面未回发时才会这样做。

是否可以在aspx页面的标记中为Activity控件定义事件处理程序?如果是这样,这会解决我的问题吗?

如果不是,我是否必须绑定中继器并连接到每个页面加载的事件才能解决我的问题(这个方法,我只是测试了它),还是有一些viewstate技巧来让事件发生坚持?页面上直放站的

标记:

<asp:Repeater ID="rptrActivites" runat="server" EnableViewState="true"> 
    <ItemTemplate> 
    <div class="activity"> 
     <crm:Activity ID="activityView" runat="server" Activity="<%#Container.DataItem %>" EnableViewState="true" /> 
    </div> 
    </ItemTemplate> 
</asp:Repeater> 

页面的后台代码:

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 

    If Not Page.IsPostBack Then 
     GetActivities() 
    End If 

    End Sub 

    Private Sub GetActivities() 

    Dim oDS As DataSet 

    'Code removed for brevity' 

    rptrActivites.DataSource = oDataView 
    rptrActivites.DataBind() 

    End Sub 

    Private Sub rptrActivites_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rptrActivites.ItemDataBound 

    If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then 
     Dim activityView As Activity = e.Item.FindControl("activityView") 
     If activityView IsNot Nothing Then 
     AddHandler activityView.OnActivityDelete, AddressOf ActivityDelete 
     End If 
    End If 

    End Sub 

    Private Sub ActivityDelete(ByVal sender As Object, ByVal e As ActivityDeleteEventArgs) 
    'This never fires' 
    End Sub 

活动控制的标记:

<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="Activity.ascx.vb" Inherits=".Activity" %> 
<!-- code removed for brevity's sake --> 
<asp:LinkButton ID="btnDelete" runat="server" Text="Delete" /> 
<!-- code removed for brevity's sake --> 

活动控制代码背后:

Public Event OnActivityDelete(ByVal sender As Object, ByVal e As ActivityDeleteEventArgs) 

Private Sub btnDelete_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnDelete.Click 
    RaiseEvent OnActivityDelete(Me, New ActivityDeleteEventArgs()) 
End Sub 
+0

尝试挂钩中继器的ItemCreated事件中的事件处理程序。项目仅绑定一次(当页面未在您的示例中发布时),但每次页面加载时都会创建它们。 关于在标记中附加事件:我没有测试它,但我认为它可以完成,你可以尝试它,但要确保ActivityDelete方法(页面中的那个方法)受到保护或公开。 – Padel 2010-06-24 16:58:08

+0

Padel,它是公开的,但我似乎没有选择在标记中分配事件。 – 2010-06-25 16:14:23

回答

1

你几乎已经回答了你自己的问题。为了在页面生命周期中触发事件,服务器需要能够始终重新创建客户端可用的所有控件。这是因为需要在服务器将视图状态加载到最前面之前创建原始控件,然后确定客户端发生的更改。一旦确定了更改,服务器就会将更改映射到适当的事件并根据需要将其解除。

听起来好像您的控件并未在每个页面呈现中始终创建,因此事件正在丢失,因为它无法附加到原始控件。

你可能想尝试的一件事是将你的Repeaters数据源放入viewstate/server属性中。这样,您只需要昂贵地获取数据以便绑定一次!Page.IsPostBack,然后可以在每次加载页面时重新绑定Repeater。然后,这应该允许您的页面识别正在触发的事件的原始控制源,将其附加并处理请求。