代码之家  ›  专栏  ›  技术社区  ›  Brandon Montgomery

ASP.NET Web用户控件事件

  •  0
  • Brandon Montgomery  · 技术社区  · 14 年前

    我创建了一个名为Activity的web用户控件。我在web用户控件上定义了一个面向公众的事件,名为OnActivityDelete。活动控件中有一个删除按钮。单击delete按钮时,Activity控件将激发OnActivityDelete事件。我正在中继器中使用此web用户控件。我为中继器的item数据绑定事件的OnActivityDelete事件分配了一个事件处理程序。当我单击Activity控件的delete按钮时,该事件从Activity控件激发,但它从未命中使用该控件的页面中的事件处理程序(我已使用调试器进入代码并确认了此行为)。

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

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

    如果没有,我是否必须绑定转发器并连接到每个页面加载的事件以解决我的问题(这是可行的,我只是测试了它),或者是否有一些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
    
    1 回复  |  直到 14 年前
        1
  •  1
  •   Brian Scott    14 年前

    你已经差不多回答了你自己的问题。为了在页面生命周期期间触发事件,服务器需要能够一致地重新创建客户端每次可用的所有控件。这是因为需要先创建原始控件,然后服务器才能在顶部加载它们的viewstate,然后识别在客户端发生的更改。一旦确定了更改,服务器将把更改映射到适当的事件,并根据需要触发它们。

    听起来您的控件不是在每个页面呈现上都一致地创建的,因此事件将丢失,因为它无法附加到原始控件。

    推荐文章