2

Webフォーム内で、asp:placeholderに追加される一連のチェックボックスを動的に作成しています

//Generates the List of Entities that may be shared
        protected void GenerateEntityList(string agencyId, string agencyName)
        {
            var selectedAgency = UserFactory.GetAgencyAndSharedDataById(Convert.ToInt64(agencyId));

            entityContainer.Controls.Clear();

            //builds the entity list based upon entities in DB
            var currentEntities = UserFactory.GetEntityList();
            //add checkboxes
            entityContainer.Controls.Add(new LiteralControl("<input type='checkbox' id='selectAllCB' value='All'>Select All<br/><br/>"));
            foreach (var item in currentEntities)
            {
                CheckBox entityCheckBox = new CheckBox();
                int currentItem = item.EntityTypeId.GetValueOrDefault(0);
                entityCheckBox.Text = item.EntityName.ToString();

                entityCheckBox.CssClass = "am_Checkbox";
                entityContainer.Controls.Add(entityCheckBox);
                entityContainer.Controls.Add(new LiteralControl("<br/><br/>"));

                //mark checkboxes as checked if currently stored in the database
                if (selectedAgency.FirstOrDefault().SecurityDataShares != null && selectedAgency.FirstOrDefault().SecurityDataShares.Count > 0)
                {
                    foreach (var ce in selectedAgency.FirstOrDefault().SecurityDataShares)
                    {
                        if (ce.EntityId == item.EntityId)
                        {
                            entityCheckBox.Checked = true;
                        }
                    }
                }
            }

作成されると、ユーザーは選択を行ったり削除したりすることができます。[更新]をクリックすると、チェックボックスから値を返す/収集して、データベースに挿入し直すことができます。

//get the text value of every checkbox 
protected void updateEnties()
{
    string receivingAgency = ReceivingAgencyID;
    long contributingAgency = QueryID;

    List<string> cbValues = new List<string>();
    foreach (CheckBox currentItem in entityContainer.Controls)
    {
        cbValues.Add(currentItem.Text);
    }
}

ただし、コレクションを反復処理しようとしても何も返されません。これにより、コントロールを誤って呼び出しているか、ポストバックのためにコントロールが破棄されていると思われます。これらの要素をプレースホルダーに書き込む代わりに、リストボックスコントロールなどの別のコントロールを使用する必要がありますか?

チェックボックスの値を取得する方法について、誰かにガイダンスを教えてもらえますか?

4

4 に答える 4

4

2つの考え方があります。1つは、最初のビュー用に作成されたコントロール階層を再作成して、ページがビューの状態とフォームの値をコントロールツリーに復元できるようにする必要があること、または2つは、ローテクソリューションを使用して簡単に取得できることです。フォームコレクションからの値。

私は個人的に、オプション2が好きで、比較的簡単に処理できます。また、を使用してHTMLを手動で作成しているように見えるためですLiteralControl。手動で作成した入力タグ間で共有される属性を指定するだけnameです(簡潔にするためにここに示す例ですが、これはおそらくあなたが行うことではありません)。

entityContainer.Controls.Add(new LiteralControl("<input type='checkbox' name='mySharedName' />");

次に、値を取得するには、次のように簡単です。

 var selectedValues = Request.Form["mySharedName"];
 // This is now a comma separated list of values that was checked

そうすれば、コントロールツリーの状態について心配する必要はありません。

于 2012-04-16T18:39:33.120 に答える
2

CheckBoxList代わりに使用して、結果セットをそれにバインドするだけで、作業がはるかに簡単になるようです。これにより、動的コンテンツの必要性が実際に無効になります。

<asp:CheckBoxList ID="CheckList1" runat="server" DataTextField="TextColumn" DataValueField="ValueColumn" ...>

それがオプションでない場合は、ポストバックごとにコントロールを再作成する必要があります。これを行うにはいくつかの方法があります。

簡単な方法

DynamicControlsPlaceHolderコントロールを確認してください。これは、舞台裏で動的コンテンツを永続化するための便利な小さなコントロールです。動的に作成されたコンテンツからすべての苦痛を取り除くので、このオプションをお勧めします。

手動による方法

中にコントロールを再作成しOnInitます。ViewStateが選択を再入力できるように、コントロールに同じIDを割り当てていることを確認してください。

protected override void OnInit(EventArgs e)
{
    var chk = new CheckBox { ID = "chkBox1" };                 
    PlaceHolder1.Controls.Add(chk);

    base.OnInit(e);
}    

ポストバック後にコントロールを再作成すると、次のような値にアクセスできるようになります。

foreach (CheckBox chk in PlaceHolder1.Controls.OfType<CheckBox>())
{
    if (chk.Checked)
    {

    }     
}
于 2012-04-16T20:02:31.913 に答える
0

皆様のご提案に感謝いたします。これがどのように実装されていたかに基づいて、私はTejsがこのソリューションの思考経路を私に送ってくれたので、その答えをクレジットしました。このプロジェクトでは、リストを作成してチェックされた要素を検証する方法のために、チェックボックスとチェックボックスリストコントロールを使用する必要がありました。課題は、asp.netがチェックボックスコントロールを生成する方法と、コントロールへの属性(名前、値など)の挿入を許可する際の制限にありました。

したがって、コードで生成されたチェックボックスから値をキャプチャするために、次のことを行いました。

aspxファイル内に、非表示の入力フィールドを追加し、runat=serverタグを割り当てました

 <input id="cbEntityList" type="hidden" runat="server" value="" />

Tejsのソリューションはこれに似ていましたが、ページ内の多くの要素のように見えるため、チェックボックスごとに非表示のフィールドを追加するというアイデアは好きではありませんでした。

次に、チェックボックスコード生成部分を変更して、オブジェクトからの一意の識別子をIDとして含めました。IDは名前属性としてhtmlにレンダリングされるため、javascript/jQueryを使用して取得できるものを取得できます。

したがって、チェックボックスを作成するforeachステートメント内に、次の行を追加しました

entityCheckBox.ID = item.EntityId.ToString();

最後に、jQueryを使用してチェックボックスのページを繰り返し、チェックされた項目のみの文字列配列を返しました。

これにより、選択されたチェックボックスに基づいて、(0,1,2,3,4)などの値が非表示のファイルに戻されます。

$('#btnUpdateEntities').click(function (event) {
        var fields;
        $(':checkbox:checked').each(function () {
            var txt = $("input[name='cbEntityList']");

            fields = ($(':checkbox:checked').map(function () {
                return this.name;
            }).get().join(","));

            $(txt).val(fields);
        });
    });

次に、コードビハインドの値の配列に次のようにアクセスできます。

string voo = cbEntityList.Value;

これが興味のある人に役立つことを願っています。

于 2012-04-17T21:38:01.290 に答える
-1

これは、オブジェクト指向の原則を使用して実装をまとめる必要がある種類のものです。この場合、おそらく独自のCheckBoxCollectionを構築する必要があります(適切なインターフェイス/クラスから継承します)。これにより、コードが簡素化され、より細分化されて拡張可能になります。

実装の詳細の1つは、説明した状況を処理することです。ビューステート/セッションなどに追加するクリックハンドラーを投入すると、テストハーネス/ユーザーがチェック/チェック解除したものを一目で確認できるはずです。

もう1つの簡単なポイント:特にCSSをすでに使用している場合は、レイアウトに<br/>タグを使用しないでください。チェックボックスが必要な表示タイプ(この場合はブロック?)であることを確認してから、コントロールを既に装飾しているCSSクラスでそれを設定できます。

tl; dr:コードで例を投げる時間はありませんが、基本的な考え方は、(好みに応じて)CheckBox()の.Checked状態をアクションから保持するCheckBoxCollection()が必要であるということです。アクションに。

于 2012-04-16T18:54:49.530 に答える