ASP .NET Web用户控制事件

时间:2010-06-24 16:42:54

标签: asp.net web-user-controls

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

我怀疑这种行为与事件处理程序在我将转发器绑定到数据源时添加到代码中的事实有关,我只在页面没有回发时才这样做。

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

如果没有,我是否必须绑定转发器并连接每个页面加载的事件以解决我的问题(这个工作,我只是测试它),或者是否有一些视图技巧来使事件保持不变?

页面上的转发器标记:

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

Page的代码背后:

  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

1 个答案:

答案 0 :(得分:1)

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

听起来你的控件没有在每个页面渲染上一致地创建,因此事件正在丢失,因为它无法附加到原始控件。

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