2010-10-27 27 views
2

請先點擊已經快把我逼瘋了2現在天 - 希望以前有人已經看到了這一點。ItemCommand不觸發在中繼器或GridView控件

我有這樣的問題,即中繼器或網格視圖內的控制的第一次點擊未能激發ItemCommand事件,隨後的每次點擊工作。該控件被加載到上Base.aspx的佔位符,像這樣

private void LoadUserControl() 
    { 
     string controlPath = LastLoadedControl; 

     if (!string.IsNullOrEmpty(controlPath)) 
     { 
      ph.Controls.Clear(); 

      UserControl uc = (UserControl)LoadControl(controlPath); 
      ph.Controls.Add(uc); 
     } 

    } 

我不知道這是否是一個視圖狀態的問題,並在頁面中的事件,我應該使用的DataBind()。我在不同的頁面事件中嘗試了數據綁定,使頁面上的視圖狀態和控件的結果無變化。

這裏的GridView的模板,但我也有一個Repeater控件相同的行爲,所以我不認爲它是這個問題的控制。

<ItemTemplate> 
     <asp:RadioButton ID="rbEnable" GroupName="MyGroup" runat="server" Text="Enabled" Checked="<%# ((EducateMe.BaseTypes.AbstractLink)Container.DataItem).IsActive == true %>" /> 
     <asp:RadioButton ID="rbDisable" runat="server" GroupName="MyGroup" Text="Disabled" Checked="<%# ((EducateMe.BaseTypes.AbstractLink)Container.DataItem).IsActive != true %>" /> 
     <asp:Button ID="btnEnable" runat="server" CommandArgument="<% # Container.DataItemIndex %>" CommandName="Enable" ToolTip="Enable" Text="Save" /> 
     <asp:Button ID="btnDisable" runat="server" CommandArgument="<% # Container.DataItemIndex %>" Visible="false" CommandName="Disable" ToolTip="Disable" Text="Disable" /> 
    </ItemTemplate> 

一些進一步的信息,這可能是相關的:

我已經注意到是在用戶控件的Page_Load事件是在那裏我重新綁定控件。這可能是控制狀態被重寫的原因,但是如果我在ascx中向該區域添加if(!IsPostback),則此代碼段不會像在aspx頁面上那樣觸發。那將是重新控制我認爲的控制的正確部分。

回答

8

MikeW,
經過數小時的擺弄,我找到了問題的根源。
它有什麼特別的做中繼器或gridview的。
這只是一個動態的控制回發問題。

解決您的問題:
令人驚訝的是,只有一行代碼丟失。
權當您加載控件,分配的東西它的ID,像這樣:

UserControl uc = (UserControl)LoadControl(controlPath); 
uc.ID = "mycontrol"; 
ph.Controls.Add(uc); 

這樣的話,當你回發,頁面知道哪些控制是哪個。

爲了更容易地解釋這一點,我們來簡化問題。
這裏是點擊一個按鈕的情況下兩次動態創建另一個按鈕一行:

  • 做一個按鈕,Button1的,點擊它會動態加載另一個按鈕,Button2的時候。假設Button2的操作與顯示當前時間一樣簡單。
  • 現在,單擊Button1。
  • 要保留Button2,必須使用ViewState來告訴頁面有一個動態控件。像你一樣,我們可以記住控制的路徑或其類的名稱。
  • 當頁面發回時,在Page_Load中,我們看ViewState,看看有一個控件我們試圖保留,所以我們在那裏加載它(這相當於上面的LoadUserControl()函數)。
  • 現在,Button2是可見的,點擊後,它會做它的行爲就好。
  • 不要單擊Button2,只需再次單擊Button1(這相當於您在兩個不同的動態控件之間切換的情況)。
  • 猜猜現在會發生什麼:Page_Load將從ViewState加載Button2。在清除佔位符後,Button1的Click事件將加載另一個Button2實例。
  • 既然你不給它分配一個ID,它會自己分配一個在UniqueID,並且在這兩個Button2s將有類似ctl02ctl03
  • 現在點擊Button2的。
  • 你會說「沒關係,我們正在覆蓋舊的」。是的,但不是沒有ID。
  • 既然你不給它一個ID,以確定它的回傳,它將利用UniqueID,將順序產生。
  • 現在頁面正在尋找ctl03,它不存在,所以Click不會觸發。
  • 但是,現在,我們有一個全新的Button2的,與UniqueIDctl02
  • 點擊這個新的Button2將工作得很好,因爲在回發中,它是唯一的Button2,所以它巧合地將有UniqueIDctl02

那麼,如何分配一個ID使其工作?
這樣,產生具有相同的ID,所以在回發,它可以找到它的尋找,它Page_Load或其他按鈕的Click事件是否是每個新生成的控制。

希望這可以解釋爲什麼它的工作原理,但至於你在乎,只是爲它分配一個ID,一切都會好的。
我認爲這將是有趣的,分享其背後的機制,爲什麼是這樣的。 =)

+0

哈 - 真棒的工作Beemer - 當然這是固定它,謝謝你的幫助堆 - 我一定會在未來看這一個:-D – MikeW 2010-10-28 23:46:34

+0

這幫了我很多!你不知道我今天因爲這個問題而遭受的挫折!我喜歡你。你讓我快樂。你完成了我...... :) – hofnarwillie 2012-02-22 20:14:05

+0

我很開心我在一年半後仍然從這個答案得到愛=)沒問題,夥計們。 – BeemerGuy 2012-02-29 20:05:46

0

我不確定你的代碼的其餘部分,但通常當我看到「第一個動作的行爲與後續動作不同」的問題時,這是因爲我在IsPostBack部分的錯誤一側放置了某些東西。

例如,我發現自己在回發時發生綁定,所以我的事件在第二次回發之前不起作用,因爲第一次回發是在他們出生時,並且初始頁面加載從未做過該部分。

我認爲你是在正確的軌道上;確保你在正確的時刻具備約束力和接線事件。

+0

感謝響應。我在帖子底部添加了一些可能相關的信息:!IsPostback。 – MikeW 2010-10-27 23:24:29

+0

嘗試將Page_Load中的重新綁定代碼移動到控件的Page_PreRender中 – BeemerGuy 2010-10-27 23:42:43

+0

那裏沒有快樂。 Viewstate打開控制和頁面順便說一句。 – MikeW 2010-10-27 23:55:21

1

我想通了,但我不明白爲什麼。
原始代碼是:

Me.rpAgreementContractors.DataSource = dtContractors 
Me.rpAgreementContractors.DataBind() 
Me.tblAgreementContractors.Visible = True 
Me.phDataPane.Controls.Add(Me.tblAgreementContractors) 

我改變了它使表可見,並把它添加到佔位符之前,我設置的數據源和約束它。問題解決了。

Me.tblAgreementContractors.Visible = True 
Me.phDataPane.Controls.Add(Me.tblAgreementContractors) 
Me.rpAgreementContractors.DataSource = dtContractors 
Me.rpAgreementContractors.DataBind() 
相關問題