QA@IT

ポップアップ画面におけるCheckBoxのChangeイベントの対処

4797 PV

お世話になります。

ASP.NET(VS2010、C#)にて開発しています。
一覧画面から、データ編集画面をポップアップ(ModalPopUp)にて表示しています。
データ編集画面では、動的にCheckBox及びTextBoxを作成しています。
※対象により、明細内容が異なるため動的に作成する必要があるため。

CheckBoxのOn/OFFでテキストボックスの入力可否を設定するため、CheckBoxのCheckedChangeイベントを
CheckBox作成時に割り当てました。
CheckedChangeを拾うため、AutoPostBackにTrueを設定したところ、CheckBoxをクリックした瞬間に、
ポップアップ画面が消えてしまいました。
また、ポップアップ画面に用意したOKボタンをクリックしたタイミングで、動的に作った各テキストの内容を参照
したかったのですが、テーブルの行を確認したら静的に作成している2レコードのみが認識されました。

ここで、実現したいのは2点あります。
1.CheckBoxのCheckedChangeイベントを動作させつつ、ポップアップ画面の表示を継続したい。
2.OKボタンのクリックイベントで動的に作成したTextboxとCheckBoxの内容を取得したい。

今月、初めてASPでの開発を始めたので、そもそもの時点で間違っているのかもしれませんが、
ご教示頂けたら助かります。

コードは下記のように記載しています。

コード
test.aspx
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
 <asp:ToolkitScriptManager ID="ToolkitScriptManager1" runat="Server" /> 
    <asp:UpdatePanel ID="updPane1" runat="server" UpdateMode="Conditional">
        <ContentTemplate>
            <ajaxToolkit:ModalPopupExtender ID="mPopup" 
                runat="server" 
                TargetControlID="DummyButton"
                PopupControlID="pnl1"
                PopupDragHandleControlID="pnl2"
                OkControlID="btnOK" 
                CancelControlID="btnCancel"
                >
            </ajaxToolkit:ModalPopupExtender>

            <asp:TableRow runat="server">
                <asp:TableCell>
                    <asp:Label ID="Label12" runat="server" Text="個別設定" > </asp:Label>
                </asp:TableCell>
                <asp:TableCell>
                    <asp:Button ID="btnKobetsu" runat="server" Text="個別設定" OnClick="btnKobetsu_Click"   />
                </asp:TableCell>
            </asp:TableRow>

            <asp:Button ID="DummyButton" runat="server" style="display: none;" />

            <asp:Panel ID="pnl1" runat="server"  >
                <asp:Panel ID="pnl2" runat="server"  >
                    <div>
                        <asp:Button ID="btnOK" runat="server" Text="ok" onclick="btnOK_Click"  />
                        <asp:Button ID="btnCancel" runat="server" Text="Cancel"  onclick="btnCancel_Click" />
                        <asp:Table ID="tblDocumen" runat="server">
                            <asp:TableRow ID="TableRow12" runat="server">
                                <asp:TableCell>
                                    <asp:Label ID="Label13" runat="server" Text="名称" > </asp:Label>
                                </asp:TableCell>
                                <asp:TableCell>
                                    <asp:Label ID="lblModalm_department_name" runat="server"></asp:Label>
                                </asp:TableCell>
                            </asp:TableRow>
                            <asp:TableRow ID="TableRow13" runat="server">
                                <asp:TableCell>
                                    <asp:Label ID="Label15" runat="server" Text="分類" > </asp:Label>
                                </asp:TableCell>
                                <asp:TableCell>
                                    <asp:Label ID="lblModalmm_departmentClass_name" runat="server" ></asp:Label>
                                </asp:TableCell>
                            </asp:TableRow>
                        </asp:Table>
                    </div>
                </asp:Panel>
            </asp:Panel>
        </ContentTemplate>
    </asp:UpdatePanel>

test.aspx.cs
 protected void btnOK_Click(object sender, EventArgs e)
    {
        int iSetCnt = -1;
        //動的に作成したコントロール数だけ配列を作成
        iContCnt = int.Parse(this.lblCtrCnt.Text);
        string[] sData1 = new string[iContCnt];
        string[] sData2 = new string[iContCnt];

        //該当するコントロールを抽出する。
        ContentPlaceHolder mpContentPlaceHolder = (ContentPlaceHolder)Master.FindControl("ContentPlaceHolder1");
        UpdatePanel upPanel = (UpdatePanel)mpContentPlaceHolder.FindControl("updPane1");
        Panel pnlDlg1 = (Panel)upPanel.FindControl("pnl1");
        Panel pnlDlg2 = (Panel)pnlDlg1.FindControl("pnl2");
        Table tbl1 = new Table();
        tbl1 = (Table)pnlDlg2.FindControl("tblDocumen");

        //コントロールを確認し、値を変数に設定する。
        foreach (Control c in tbl1.Controls)
        {
            if (c is TableRow)
            {
                foreach (Control rc in c.Controls)
                {
                    if (rc is TableCell)
                    {
                        foreach (Control cc in rc.Controls)
                        {

                            if (cc is CheckBox)
                            {
                                iSetCnt += 1;

                                TextBox oTx = new TextBox();
                                CheckBox oCk = (CheckBox)cc;
                                string sName = "txtDocName_" + oCk.ID.Replace("chkDocName_", "");
                                oTx = (TextBox)tbl1.FindControl(sName);
                                sData1[iSetCnt] = oTx.Text;                     //データ1
                                if (oCk.Checked == true)
                                {
                                    sData2[iSetCnt] = "1";
                                }
                                else
                                {
                                    sData2[iSetCnt] = "0";
                                }
                            }
                        }
                    }
                }
            }
        }
    }

protected void getDocumentType()
{
    //変数宣言
    CheckBox chkDef = new CheckBox();

    //更新するデータを取得する。
    System.Data.DataTable dt = this.gdtf_getSearchDepartment();
    System.Data.DataRow dr;

    //データ件数分だけチェックボックスを追加する。
    for (int i = 0; i < dt.Rows.Count; i++)
    {
        chkDef = new CheckBox();

        //データテーブルの行を1行追加する。
        dr = dt.Rows[i];

        lblTitle.Text = "通知先(XXX)";
        lblTitle.ID = "lblDocName_" + dr[0].ToString();

        chkDef.Text = "デフォルト?";
        chkDef.ID = "chkDocName_" + dr[0].ToString();
        chkDef.CheckedChanged += new EventHandler(chkDef_CheckedChanged);
        chkDef.AutoPostBack = true;

        //追加
        //1行目1列目にラベル、2列目にチェックボックス
        //2行目2列目にテキストボックス
        //1列目はRowSpan=2

    }
}

protected void chkDef_CheckedChanged(object sender, EventArgs e)
{
    //該当するコントロールを抽出する。
    CheckBox och = (CheckBox)sender;
    string sName = "txtDocName_" + och.ID.Replace("chkDocName_", "");

    ContentPlaceHolder mpContentPlaceHolder = (ContentPlaceHolder)Master.FindControl("ContentPlaceHolder1");
    UpdatePanel upPanel = (UpdatePanel)mpContentPlaceHolder.FindControl("updPane1");
    Panel pnlDlg = (Panel)upPanel.FindControl("pnlDialog");
    Panel pnlDlgD = (Panel)pnlDlg.FindControl("pnlDialogDetail");
    Table tbl1 = new Table();
    tbl1 = (Table)pnlDlgD.FindControl("tblDocumen");
    TextBox oTx = new TextBox();
    oTx = (TextBox)tbl1.FindControl(sName);

    //チェックがOnならメール欄入力不可とする。
    if (och.Checked == true)
    {
        oTx.Enabled = false;
    }
    else
    {
        oTx.Enabled = true;
    }

    //ポップアップ画面を再表示する。
    this.mPopup.Show();
}
  • 問題を再現するのに必要最低限にコードを絞ってそれをアップするということはできませんか? その過程で自己解決できるかもしれませんし。 -

回答

コードは余計なところがあるかと思えば、肝心な部分が書いてなかったり、おかしな記述があったりで理解できないので、コードは見ないで説明文のところだけ見てコメントします。

ModalPopup を使用するなら、同一ページに「一覧画面」「データ編集画面」その他必要なものを全て実装し、必要ならポストバックしてサーバー側で処置を行い、そのページで最終結果を得るのが基本です。

その過程で、ModalPopup の機能を利用して特定の部分(質問者さんのケースでは「データ編集画面」)の表示・非表示を切り替えることになるはずです。

なので、まず、ModalPopup を使わないで動かしてみてください。間違いなく実装されていればきちんと動いて期待した結果が得られるはずです。(もちろん、ModalPopup で「データ編集画面」の表示・非表示を切り替える機能は除いてですが)

ModalPopup 関係のコードをコメントアウトすれば、上で述べたことは試すことができると思います。やってみてください。

多分、少なくとも「動的に作成したTextboxとCheckBoxの内容を取得」のところは期待の動作はしないのではないかと思います。

動的に生成したサーバーコントロールは、ポストバックするたび再度動的に生成する必要があります。それがされてますか?

ModalPopup なしで 2 の問題(他にもあれば全て)を解決してください。その後で、どのタイミングでどのように「データ編集画面」の表示・非表示を切り替えるかを考えて、1 の問題を解決してはいかがですか?

編集 履歴 (1)
  • お世話になります。
    ModalPopup関係のコードをコメントアウトして確認してみました。
    確かに、動的に作成したコントロールは全て消えておりました。
    そのため、ポストバックする度にコントロールを生成するようにはしたのですが、ポストバック前に各コントロールに設定した内容が保持できません。
    値を保持するにはどのようにしたらいいのでしょうか?
    -
  • タイミングの問題かも。以下の記事に書いてある "コントロールの動的作成は、WebForm1 クラスによって提供される OnInit 関数内で行うのが最良です" に従ってやってみてください。
    http://support2.microsoft.com/default.aspx?scid=kb;ja;317794
    -
  • 確認遅くなりました。
    -
ウォッチ

この質問への回答やコメントをメールでお知らせします。