2009-07-24 24 views
4

私にはテーブルがあり、処理する行を選択できるようにする必要があります。私はテーブルにチェックボックスの列を追加する方法を考え出しましたが、フォームの送信時にチェックされているかどうかをテストする方法を見つけることができません。静的要素の場合は、this.theCheckBoxを確認するだけで、プログラムで生成されます。ASP.NETのチェックボックスのリストをプログラムで作成して使用するにはどうすればよいですか?

また、私は自分のデータを(IDプロパティに詰め込んで)どのように付けているのかよく分かりません。

私はそれが関連するかどうか分からないが、私は、私は再実行する前にチェックした周り前回作成されたチェックボックスのどの知られている必要があるように私がキャッチ22のビットで探していますそれらを作成したコード


編集:私はほとんど解決策を見つけたAutoPostBack財産とCheckedChangedイベントを設定することにより:

checkbox.AutoPostBack = false; 
checkbox.CheckedChanged += new EventHandler(checkbox_CheckedChanged); 

私は戻って変更されているすべてのチェックボックスのポストに呼ばれるようにコードを取得することができます。しかし、これには2つの問題がある:

私はこの情報
  • コールバックを使用する必要があり、コールバック(私はわからない、または中に)後に処理されるがPage_Loadたチェックボックスのために呼び出されていない
    • ページが読み込まれているときにチェックされます。

    編集2:

    の上部にある既知のプレフィックスと詰め物これですべての私のIDをタグ付けされた私は何をやってしまった:

    foreach (string v in this.Request.Form.AllKeys) 
    { 
        if (v.StartsWith(Prefix)) 
        { 
         var data = v.Substring(Prefix.Length); 
        } 
    } 
    

    他のすべて遅くまで走っているようだ。

  • 答えて

    0

    :他

    foreach (string v in this.Request.Form.AllKeys) 
    { 
        if (v.StartsWith(Prefix)) 
        { 
         var data = v.Substring(Prefix.Length); 
        } 
    } 
    

    すべては後半に実行しているようです。

    1

    まず、各チェックボックスにIDがあり、タグに 'runat = "server"'があることを確認します。

    次に、FindControl()関数を使用して検索します。例えば

    、あなたはGridViewの内のすべての行をループしている場合..

    foreach(GridViewRow r in Gridview1.Rows) 
    { 
    
        object cb = r.FindControl("MyCheckBoxId"); 
        if(r != null) 
        { 
         CheckBox chk = (CheckBox)cb; 
         bool IsChecked = chk.Checked; 
        } 
    
    } 
    
    +0

    私は 'runat'を設定する方法を見つけることができません。 'CheckBox() 'を使ってチェックボックスを' Form_Load'内で生成するだけで、タグに編集することはできません – BCS

    +0

    コントロールが動的に追加され、ASPコントロールなので、runatを設定する必要はありません属性。コントロールのすべての属性を正しく設定し、イベントハンドラを追加すると、デザイン時に追加された他のコントロールと同じように機能します。追加されたチェックボックスの数がわかっていれば、ループを実行してIDを構築することで@DavidのFindControlメソッドを使用できますが、複数のコントロールを扱うときに親コンテナを直接ループするよりも効率が悪いです。 –

    +0

    私はチェックしていませんが、再生した後にしか見つからないという問題を抱えていると思われます。 – BCS

    2

    私はあなたがDataListコントロールを使用していると仮定するつもりですが、これはテンプレート化することができると連携して制御する必要があります。また、DataBindingを使用していると仮定します。

    コードフロント:背後に

    <asp:DataList ID="List" OnItemDataBound="List_ItemDataBound" runat="server"> 
        <ItemTemplate> 
         <asp:CheckBox ID="DeleteMe" runat="server"/> 
         <a href="<%# DataBinder.Eval(Container, "DataItem.Url")%>" target="_blank"> 
          <%# DataBinder.Eval(Container, "DataItem.Title")%></a> 
        </ItemTemplate> 
    </asp:DataList> 
    <asp:Button ID="DeleteListItem" runat="server" OnClick="DeleteListItem_Click" ></asp:Button> 
    

    コード:

    public partial class Default : System.Web.UI.Page 
    { 
        protected void Page_Load(object sender, EventArgs e) 
        { 
         if (!IsPostBack) 
          LoadList(); 
        } 
    
        protected void DeleteListItem_Click(object sender, EventArgs e) 
        { 
         foreach (DataListItem li in List.Items) 
         { 
          CheckBox delMe = (CheckBox)li.FindControl("DeleteMe"); 
    
          if (delMe != null && delMe.Checked) 
            //Do Something 
          } 
         } 
    
         LoadList(); 
        } 
    
        protected void LoadList() 
        { 
         DataTable dt = //Something... 
         List.DataSource = dt; 
         List.DataBind(); 
        } 
    
        protected void List_ItemDataBound(object sender, DataListItemEventArgs e) 
        { 
         if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item) 
         { 
          string id = DataBinder.Eval(e.Item.DataItem, "ID").ToString(); 
          CheckBox delMe = (CheckBox)e.Item.FindControl("DeleteMe"); 
    
          if (delMe != null) 
           delMe.Attributes.Add("value", id);     
         } 
        } 
    } 
    
    +0

    私はそれらの事のどちらかを使用していません。 OTOH私は、ItemTemplateが何をしているかを調べる必要があります。 – BCS

    0

    あなたの投稿は少しあいまいです。これは、テーブルにコントロールを追加する方法を確認するのに役立ちます。それはASP:Tableか、通常のHTMLテーブルですか(おそらくrunat = "server"属性が付いているので、項目を追加しています)?

    ユーザが選択肢をたくさん作ってくれるようにする場合は、「Submit」ボタンを押して、チェックした行に基づいて各行を処理すると、CheckChangedイベントを処理しないでください。それ以外の場合は、気づいたとおり、毎回ポストバックが発生し、他のチェックボックスは処理されません。したがって、CheckBoxを作成するときにイベントハンドラを設定しないでください。そうすれば、ポストバックは発生しません。

    サブミットボタンのイベントハンドラでは、各テーブル行、セルをループし、セルの子コントロールにチェックボックスが含まれているかどうかを判断します。

    私はテーブルを使用しないことをお勧めします。あなたがおそらくGridViewまたはDataListを記述しているから、より良い選択肢です。


    EDIT:ここに実証するための簡単な例です。テストするために、これを新しいプロジェクトで動かすことができるはずです。

    マークアップ

    <form id="form1" runat="server"> 
        <div> 
        <table id="tbl" runat="server"></table> 
        <asp:Button ID="btnSubmit" runat="server" Text="Submit" 
         onclick="btnSubmit_Click" /> 
        </div> 
        </form> 
    

    コードビハインド

    +0

    これはHTMLテーブルです。私はチェック行を処理したいだけですが、CheckChangedはそのためには動作しません。 'Click'ハンドラでasp:Buttonを追加した後、Form_Loadの後にも遅く実行されることがわかりました。間違った場所にあるかもしれません。 – BCS

    +0

    AutoPostBackをfalseに設定しているため、CheckChangedはトリガされません。 trueに設定する必要があります。あなたがそれぞれの小切手にポストバックしても大丈夫なら、あなたはそれを行うことができます。それ以外の場合は、送信ボタンをクリックするとすぐにそれらをすべて処理します。その場合は、私が投稿したものと同様のループでそれらを処理します。 –

    +0

    HTMLテーブルのシナリオでどのように動作するかをデモするサンプルを追加しました。 –

    1
    protected void Page_Load(object sender, EventArgs e) 
    { 
        for (int i = 0; i < 10; i++) 
        { 
         var row = new HtmlTableRow(); 
         var cell = new HtmlTableCell(); 
         cell.InnerText = "Row: " + i.ToString(); 
         row.Cells.Add(cell); 
         cell = new HtmlTableCell(); 
         CheckBox chk = new CheckBox() { ID = "chk" + i.ToString() }; 
         cell.Controls.Add(chk); 
         row.Cells.Add(cell); 
         tbl.Rows.Add(row); 
        } 
    } 
    
    protected void btnSubmit_Click(object sender, EventArgs e) 
    { 
        foreach (HtmlTableRow row in tbl.Rows) 
        { 
         foreach (HtmlTableCell cell in row.Cells) 
         { 
          foreach (Control c in cell.Controls) 
          { 
           if (c is CheckBox) 
           { 
            // do your processing here 
            CheckBox chk = c as CheckBox; 
            if (chk.Checked) 
            { 
             Response.Write(chk.ID + " was checked <br />"); 
            } 
           } 
          } 
         } 
        } 
    } 
    

    ポストバックデータはINITCOMPLETEイベントとプリロードイベントの間に復元されます。チェックボックスが後で作成されるまでチェックボックスが作成されない場合、チェックボックスはイベントに「追いつき」を再生し、データは作成後直ちにコントロールにロードされます。
    これが遅れている場合は、あなたが何をしているかのような何かをする必要があります。つまり、投稿データがコントロールに渡される前にアクセスする必要があります。
    CheckBoxUniqueIdを保存することができれば、特別なプレフィックスを与えなくても、投稿データに直接アクセスできます。これを行うには、生成時にIDを保存してビューの状態に保存する文字列のリストを作成します。もちろん、ビューステートを有効にする必要があり、ビューステートでより多くのスペースを占有します。

    foreach (string uniqueId in UniqueIds) 
    { 
        bool data = Convert.ToBoolean(Request.Form[uniqueId]); 
        //... 
    } 
    
    +0

    最初のビットは知っておくと良いです。 UniqueIdのビットについては、むしろ無国籍のままにしておきたい。 – BCS

    0

    CheckBoxListコントロールを使用するとどうなりますか?今はVisual Studioが公開されていませんが、実行時にリストを提供できるDataSourceDataBind()を提供するDataBoundコントロールであることを覚えておいてください。ページがポストバックを行うときは、myCheckBoxList.Itemsのようなものを呼び出してリストを走査し、ListItem.Selectedメソッドを呼び出して現在のアイテムが選択されているかどうかを確認できます。これはうまくいくはずです。

    +0

    私は決して日付バインディングを使用していないので、それは欠点です。別の懸念事項: 'DateSource'からデータを読み込む前に*処理できるかどうか知っていますか?これは、前のページの読み込みに使用されたデータに基づいています。 – BCS

    +0

    私は間違った方法であなたの質問を解釈したと思います。 CheckBoxListは、達成したいものには適していません。ただし、データバインディングのメカニズムが役立つ可能性があります。 "前処理" ...理論的には、 "!Page.isPostBack"のケースでコントロールをロードするだけで、ViewStateは再びデータバインドされたコントロール(Repeater、Gridなど)に元のアイテムを再度マップします。残念ながら、私は現時点でそれを確認することはできませんが、FindControl(...)メソッドを使用してチェックボックスを取得する方法が必要です。 – Juri

    0

    PageのCreateChildControlsメソッドのオーバーライドで追加します。彼らにIDを与えてください!このようにして、正しい時間にコントロールツリーに追加されます。

    IMHO DataBound Templated Control、つまりListView(.NET 3.5)のようなものを使用するのが最善の方法です。ポストバック後のページロードでは、データバインドされたコントロール内のすべてのアイテムをトラバースし、実際のチェックボックスで取得するにはitem.FindControlを使用します。 の上部にある既知のプレフィックスと詰め物これですべての私のIDをタグ付けされた私は何をやってしまった

    +0

    最初のオプションは、チェックボックスを作成する前に処理が必要なので機能しません。処理によって作成されるチェックボックスに影響が出るからです。 OTOH私はこのDataBoundのものを調べ、それがどういうものかを見なければならないでしょう。 – BCS

    関連する問題