2010-06-24 65 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。然後,這應該允許您的頁面識別正在觸發的事件的原始控制源,將其附加並處理請求。