我创建了一个名为Activity的Web用户控件。我已经在该网络用户控件上定义了一个面向公共的事件,称为OnActivityDelete。活动控件中有一个删除按钮。单击“删除”按钮时,活动控件会发射onActivityDelete事件。我正在中继器中使用此Web用户控件。我将事件处理程序分配给中继器项目数据绑定事件的OnActivityDelete事件。当我单击“活动控件”删除按钮时,该事件会从活动控件中启动,但是它从未在使用该控件的页面中击中事件处理程序。 (我已经使用调试器介入了代码,并确认了这种行为)。

我的怀疑是,这种行为与以下事实有关:事件处理程序在我将Repeater绑定到数据源时,将事件处理程序添加在代码后面,我只有在页面没有发布后才这样做。

是否可以在ASPX页面的标记中定义活动处理程序的活动处理程序?如果是这样,这会解决我的问题吗?

如果没有,我是否必须将中继器绑定并连接到每个页面加载以解决我的问题(这起作用,我只是对其进行了测试),或者是否有一些视图的技巧来使事件坚持不懈?

页面上的中继器标记:

<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
有帮助吗?

解决方案

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

听起来您的控件并非在每个页面渲染上都始终如一地创建,因此由于无法将其附加到原始控件上,因此丢失了该事件。

您可能想尝试的一件事是将RepeAter DataSource放入ViewState / Server属性中。这样一来,您只需要付出额外的数据即可在!page.ispostback上绑定一次,然后可以始终如一地重新启动每个页面上的中继器。然后,这应该允许您的页面识别要触发事件的原始控制源,将其附加,然后处理请求。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top