2017-11-26 10 views
0

私は過去数時間の検索に費やしましたが、私の問題の解決策を見つけることができません。タイトルはかわいらしいですが、私の状況を正確に表していると思います。下記のコードを参照してください。私はリピータのItemDataBoundイベントでSelectedIndexChanged関数を追加しようとしましたが、ポストバックイベントのようにページがハンドラを忘れてしまうようです。 Triggers.Addを使用してAsyncPostbackTriggerを追加する場合も同じです。UpdatePanel RadioButtonList AsyncPostback EventHandler Lost

ポストバック時にEventHandlerを再追加する方法がありましたが、これは私にとっては実行可能な解決策ではありません。実際のDataBindingとは独立したリピータDataSourceをループするカスタム関数を記述し、適用可能な場合は特にEventHandlerを再バインドすることもできますが、これは非常に強力なアプローチです。私の目的を達成する良い方法はありますか?

フロントエンド:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> 

<!DOCTYPE html> 

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
    <title></title> 
</head> 
<body> 
    <form id="form1" runat="server"> 
     <asp:ScriptManager ID="smMain" runat="server" /> 
     <div> 
      <asp:UpdatePanel ID="updTest" runat="server" UpdateMode="Conditional"> 
       <ContentTemplate> 
        <asp:Repeater ID="rptTest" runat="server" OnItemDataBound="rptTest_ItemDataBound"> 
         <ItemTemplate> 
          <asp:RadioButtonList ID="rblTest" runat="server" RepeatDirection="Horizontal" ClientIDMode="AutoID" /> 
         </ItemTemplate> 
        </asp:Repeater> 
       </ContentTemplate> 
      </asp:UpdatePanel> 
     </div> 
    </form> 
</body> 
</html> 

バックエンド:

using System; 
using System.Collections.Generic; 
using System.Data; 
using System.Linq; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

public partial class _Default : System.Web.UI.Page 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     if (!Page.IsPostBack) 
     { 
      DataTable dt = new DataTable(); 

      dt.Columns.Add("Test"); 

      DataRow dr = dt.NewRow(); 

      dr["Test"] = "FirstRow"; 

      dt.Rows.Add(dr); 

      dr = dt.NewRow(); 

      dr["Test"] = "SecondRow"; 

      dt.Rows.Add(dr); 

      rptTest.DataSource = dt; 
      rptTest.DataBind(); 
     } 
     else 
     { 
      // This works, but it's very, very ugly. Also, I have no way of being able to test for which function I actually want to call! 
      ((RadioButtonList)FindControl(Request.Params["__EVENTTARGET"])).SelectedIndexChanged += testFunction; 
     } 
    } 

    protected void rptTest_ItemDataBound(object sender, RepeaterItemEventArgs e) 
    { 
     RadioButtonList rbl = (RadioButtonList)e.Item.FindControl("rblTest"); 

     DataTable dt = new DataTable(); 

     dt.Columns.Add("ButtonName"); 
     dt.Columns.Add("ButtonID"); 

     DataRow dr = dt.NewRow(); 

     dr["ButtonName"] = "Yes"; 
     dr["ButtonID"] = "1"; 

     dt.Rows.Add(dr); 

     dr = dt.NewRow(); 

     dr["ButtonName"] = "No"; 
     dr["ButtonID"] = "2"; 

     dt.Rows.Add(dr); 

     rbl.DataTextField = "ButtonName"; 
     rbl.DataValueField = "ButtonID"; 
     rbl.DataSource = dt; 
     rbl.DataBind(); 

     rbl.AutoPostBack = true; 
     //This doesn't work. Even though it's set here, it doesn't "remember" the setting on postback 
     //rbl.SelectedIndexChanged += testFunction; 
     //This doesn't work either. Again, it doesn't "remember" the setting on postback 
     //updTest.Triggers.Add(new AsyncPostBackTrigger() { ControlID = rbl.UniqueID }); 
    } 

    private void testFunction(object sender, EventArgs e) 
    { 

    } 
} 

答えて

0

は、問題への解決策を見つけました。基本的には、ItemDataBoundイベントではなく、ItemCreatedイベントでEventHandlerをバインドする必要があります。 ItemCreatedイベントは、最初のポストバックだけでなく、各ポストバックに対して起動されるため、EventHandlerを適切に再バインドできます。

フロントエンド:

<asp:Repeater ID="rptTest" runat="server" OnItemCreated="rptTest_ItemCreated" OnItemDataBound="rptTest_ItemDataBound"> 

バックエンド:

protected void rptTest_ItemCreated(object sender, RepeaterItemEventArgs e) 
{ 
    RadioButtonList rbl = (RadioButtonList)e.Item.FindControl("rblTest"); 

    rbl.SelectedIndexChanged += testFunction; 
}