2012-04-10 20 views
1

階層型検索を行うページがあります。ドロップダウンリストから開始し、ドロップダウンリストで選択した値に基づいてデータベースにクエリを表示します子が別のドロップダウンリストにあり、これが葉に当たっている限り続きます。最初のドロップダウンが動的に追加され、SelectedIndexChangedにイベントハンドラがあります。ただし、選択した値を変更すると、ポストバックがトリガーされますイベントハンドラメソッドを呼び出さない ..私はここで間違って何をしているのかわからないか、それはバグですか?動的に生成された制御asp.net - ポストバックでイベントハンドラメソッドを呼び出さない動的に作成されたドロップダウン

ページロードで
protected override void LoadViewState(object savedState) 
    { 
     base.LoadViewState(savedState); 

     // regenerate the persisted controls 
     foreach (var prop in PersistedControls) 
     { 
      CreateControl(prop); 
     } 

    } 

を再現し、作成されたコントロール

private List<DynamicControlProperties> PersistedControls 
    { 
     get 
     { 
      if (_persistedControls == null) 
      { 
       if (Session[PersistedControlsKey] == null) 
       { 
        Session[PersistedControlsKey] = new List<DynamicControlProperties>(); 
       } 

       _persistedControls = Session[PersistedControlsKey] as List<DynamicControlProperties>; 
      } 

      return _persistedControls; 
     } 
    } 

、ページのInitで

を追跡保つためにセッション変数を使用して

、非常に最初のドロップダウンを作成し

protected void Page_Load(object sender, EventArgs e) 
    { 


     if (!Page.IsPostBack) 
     { 
      // create the control 
      CreateControl(....) 

      // bind the data to the dropdown 
     } 
    } 

コントロールの作成方法では、ラベルとドロップダウンのラップを作成するだけですそれはここでホルダー

private DropDownList CreateControl(DynamicControlProperties dynamiccntrlprop) 
    { 
     // create a new HTML row 
     HtmlGenericControlWithParentID tr = new HtmlGenericControlWithParentID("tr"); 
     HtmlGenericControlWithParentID td1 = new HtmlGenericControlWithParentID("td"); 
     HtmlGenericControlWithParentID td2 = new HtmlGenericControlWithParentID("td"); 

     // make sure we set the id and parentid 
     tr.ID = string.Format("tr{0}", dynamiccntrlprop.ID);    
     tr.ParentID = dynamiccntrlprop.ParentID; 
     tr.EnableViewState = true; 

     // create a new label for dropdown 
     Label lbl = new Label() { ID = string.Format("lbl{0}", dynamiccntrlprop.DisplayName), Text = dynamiccntrlprop.DisplayName }; 

     // create a new dropdown list 
     DropDownList ddl = new DropDownList() 
     { 
      ID = string.Format("ddl{0}", dynamiccntrlprop.DisplayName), 

      // set the postback 
      AutoPostBack = true, 

      EnableViewState = true 
     }; 

     // subscribe for the select index changed event 
     ddl.SelectedIndexChanged += new EventHandler(ddl_SelectedIndexChanged); 

     // add the controls to table row 
     td1.Controls.Add(lbl); 
     td2.Controls.Add(ddl); 

     tr.Controls.Add(td1); 
     tr.Controls.Add(td2); 

     // add the control to place holder  
     this.filtersPlaceHolder.Controls.Add(tr); 

     return ddl; 

    } 

を配置するために、それを追加する内側インデックスは、ハンドラを変更し、

protected void ddl_SelectedIndexChanged(object sender, EventArgs e) 
{ 
} 

は、ビューステート、AutoPostBackの何とか何とか何とか...バックポストに同じIDを持つコントロールを再作成を有効.. googleのすべての答えを試してみました..しかし運がいい..私は、インデックスを変更したが、イベントハンドラメソッドを呼び出さないときは、ポストバックをトリガします..

私は何か考えますか?

あなたはCreateControlメソッドは、それぞれ、すべてのページのポストバックで呼び出されることを確認する必要があり、多くのおかげで、 K

答えて

1

。これは、ポストバック後にダイナミックコントロールのイベントハンドラが確実にフックアップされるようにする必要があります。

protected void Page_Load(object sender, EventArgs e) 
{ 
    // you shouldn't wrap the call to CreateControl in this 'if' statement 
    //if (!Page.IsPostBack) 
    //{ 
      // create the control 
      CreateControl(....) 

      // bind the data to the dropdown 
    //} 
} 

これを実行すると、選択したインデックス変更イベントが発生します。

+0

@karthik:あなたはこれを試してみました、それは動作しますか? – Marcel

0

多分、ドロップダウンリストの新しい値が読み込まれません。 保護されたオーバーライドボイドLoadViewState(savedStateオブジェクト) {

// regenerate the persisted controls 
    foreach (var prop in PersistedControls) 
    { 
     CreateControl(prop); 
    } 

    base.LoadViewState(savedState); 
}