2012-02-24 7 views
0

動的に入力できる行を作成するUIを作成しようとしています。パネル内の動的に作成されたDropDownListがイベント処理を許可していません

私はDropDownListを含むパネルに自分のリストを追加することができ、関連する削除ボタンがあります。

[削除]ボタンには、その特定のパネルを削除できるOnClickイベントの境界があります。

SelectedIndexChanged EventHandlerをDropDownListにバインドしようとすると問題が発生します。

これは、すべてのポストバック後にコントロールを再作成する方法と関係があると思われます。

「これを追加するかコードでこれを変更してください」という質問はしません。私は本当にどこに間違っているのか理解したいと思っています。申し訳ありません。 :s

protected void Page_Load(object sender, EventArgs e) 
{ 
    //Showing this for the the poster that asked. 
    if (!IsPostBack) 
    { 
     GetClustersFromDB(user); 
     BindGrid(); 
     BindState();    
    } 
    if (Session["persistControls"] != null) 
    { 
     persistControls = (List<Panel>)Session["persistControls"]; 
     int count = 0; 

     foreach (Panel dynamicControl in persistControls) 
     { 
      DropDownList list = new DropDownList(); 
      list.ID = "list" + count; 
      list.SelectedIndexChanged += new EventHandler(list_SelectedIndexChanged); 
      list.AutoPostBack = true; 
      list.Items.Add(new ListItem("", "0")); 
      list.Items.Add(new ListItem("Title", "1")); 

      dynamicControl.ID = "panel" + count; 

      Button btnRemove = new Button(); 
      btnRemove.Click += new EventHandler(btnDelete_Click); 
      btnRemove.Text = "Remove"; 
      btnRemove.CommandArgument = count.ToString();    

      myPlaceholder.Controls.Add(dynamicControl); 
      myPlaceholder.Controls.Add(btnRemove); 
      count++; 
     } 
    } 
} 

protected void btnAdd_Click(object sender, EventArgs e) 
{ 
    try 
    { 
     DropDownList list = new DropDownList(); 
     list.SelectedIndexChanged += new EventHandler(list_SelectedIndexChanged); 
     list.AutoPostBack = true; 
     list.Items.Add(new ListItem("", "0")); 
     list.Items.Add(new ListItem("Title", "1")); 

     Panel panelContainer = new Panel(); 
     panelContainer.ID = "panel" + persistControls.Count; 

     panelContainer.Controls.Add(list); 

     Button btnRemove = new Button(); 
     btnRemove.Click += new EventHandler(btnDelete_Click); 
     btnRemove.Text = "Remove"; 
     btnRemove.CommandArgument = persistControls.Count.ToString(); 
     myPlaceholder.Controls.Add(panelContainer); // Pushes the Panel to the page. 
     persistControls.Add(panelContainer);// Adds our Panel to the Control list 

     myPlaceholder.Controls.Add(btnRemove); // Pushes our Button to the page. 
     Session["persistControls"] = persistControls; // put it in the session 
    } 
    catch 
    { 
     throw; 
    } 
} 

protected void btnDelete_Click(object sender, EventArgs e) 
{ 
    try 
    { 
     int deleteThisOne = int.Parse(((Button)sender).CommandArgument); 
     persistControls.Remove(persistControls[deleteThisOne]); 
     Session["persistControls"] = persistControls;   
     Response.Redirect(Request.Url.ToString()); 
    } 
    catch 
    { 
     throw; 
    } 
} 

protected void list_SelectedIndexChanged(object sender, EventArgs e) 
{ 
    throw new NotImplementedException(); 
} 

//aspx File Snippets 
<asp:Button ID="btnAdd" runat="server" Text="Add Control" onclick="btnAdd_Click" /> 
<asp:Button ID="btnClear" runat="server" Text="Reset" onclick="btnClear_Click"/> 
<asp:PlaceHolder ID="myPlaceholder" runat="server"></asp:PlaceHolder> 
+0

ここで、list_SelectedIndexChangedハンドラメソッドはありますか? –

+0

こんにちはアレックス、それはcsコードの残りの部分と同じ場所にあります..asp.csファイル。私は関数にブレークポイントを設定し、デバッグ中はトリガすることができませんでした。 – Intern1990

+0

**最初の投稿にコードを追加しましたが、編集することができませんでした。 – Intern1990

答えて

0

このようなコントロールを維持することは本当の苦痛です。

  1. 各パネルに表示するデータをカプセル化する(小さい)クラスを作成します。
  2. セッション内にこれらのオブジェクトのListを維持します。
  3. <asp:Repeater>を使用して、アイテムをデータバインドして一覧に表示します。
  4. リピータのItemTemplateには、<asp:DropDownList>を含む<asp:Panel>を書き出すことができます。ドロップダウンリストのItemCommandプロパティを使用して、それをサーバー側イベントハンドラにバインドします。同様に、をテンプレートに入れ、これのItemCommandプロパティを別のサーバー側イベントハンドラにバインドすることもできます。
  5. [追加]をクリックすると、サーバーにポストバックし、リストに追加し、セッションで保存してリピータを再バインドします。
  6. 削除をクリックすると、サーバーにポストバックし、リストから項目を削除し、セッションで保存して、リピータを再バインドします。

この方法により、ASP.Netはすべてのコントロールの作成を処理します。しかし、あなたが本当に自分ですべてをしたい場合は、このInfinities Loop blog postが必要です。

+0

グラハムありがとう!ちょうど説明のために...それぞれの "行"は、その左側のコントロールの選択に基づいてポピュレートする予定でした。理想的には、各パネルの内容をパラメータとしてストアドプロシージャに渡してから、それからデータをバインドします。あなたの意見では、これは私の問題のより良いデザインアプローチですか? – Intern1990

+0

OKですので、「追加」をクリックしてポストバックすると、コントロールの値を調べ、これらに基づいてリストオブジェクトを設定することができます。うまくいけばそれは意味がある、私はあなたのページのレイアウトを理解しているとは思っていません。 –

+0

それはいい話ですが、私が投稿した内容をもう一度読んだだけで奇妙に聞こえます。 3つのボタン(Add Row Clear RowとSearch)があります。 Add Rowをクリックすると、DropDownListを含むPanelが作成されます。そのDropDownListから、別のコントロールを作成するオプションを選択します。最終的に複雑なselectステートメントのUIコンポーネントを提供します。 行をクリアするだけで、コントロールセッションがクリアされます。 検索では、各コントロールのEventHandlingによって設定されたパネル内のコントロールの "行"からの情報が渡されます。 – Intern1990

0

これはうまくいかないと思います。 PageLoadイベントでドロップダウンリストを作成すると、ビューステートは決してバインドされず、ユーザーが選択したオプションは決して表示されません。

コントロールOnInitを作成すると、PostBackが発生したときにViewStateデータがコントロールにバインドされ、そのコントロールにアクセスできます。

関連する問題