none
GridViewに個別に実装したチェックボックスのture or false判定がされない RRS feed

  • Frage

  • 【発生環境】
    ・Visual Studio 2019(VS2019)
    ・Windows10 Pro

    【症状】
    GridViewに個別で実装したチェックボックスをjavascriptにて一括選択と一括解除行うボタンを追加実装しました。
    そのjavascriptで実装した一括選択または一括解除を行った後、手動にてチェックボックスを操作します。
    そのチェックされた値を取得すると、手動でチェックした値が反映されていません。

    ・GridView_AにDataTableクラスを用いて、データをDataBindする。
                // DataTable定義
                DataTable dt = new DataTable();
                dt.Columns.Add("✓");
                dt.Columns.Add("A");
                dt.Columns.Add("B");
                dt.Columns.Add("C");

                foreach (var x in lRtrn)
                {
                    // DataTableにデータ追加
                    DataRow row = dt.NewRow();
                    row["✓"] = x.Seq;
                    row["A"] = x.Seq;
                    row["B"] = x.B;
                    row["C"] = x.C;
                    dt.Rows.Add(row);
                }
                // GridViewにバインド
                this.GridView_A.DataSource = dt;
                this.GridView_A.DataBind();
     
    ・GridViewにデータをバインドする時に発生するイベントRowDataBoundに、チェックボックスを実装する処理を書きます。
            protected void GridView_A_RowDataBound(object sender, GridViewRowEventArgs e)
            {
                if (e.Row.DataItem == null
                    && e.Row.RowType != DataControlRowType.Header)
                {
                    return;
                }
                // GridView Header設定
                if (e.Row.RowType == DataControlRowType.Header)
                {
                }
                // GridView Data設定
                else if (e.Row.RowType == DataControlRowType.DataRow)
                {
                    // チェックボックス数をSessionへ
                    int iCkbCont = (int)Context.Session["count"];
                    // チェックボックス生成
                    CkbRtrnItem[iCkbCont].ID = "CKB" + e.Row.Cells[0].Text;
                    CkbRtrnItem[iCkbCont].Attributes.Add("SEQ", e.Row.Cells[0].Text);
                }
     
    ・aspx側にjavascriptで表示されたデータ分のすべてのcheckedプロパティの値をtrue / falseに設定するボタンを追加し、以下のようなスクリプトを参照します。
            $(function ()
            {
                $('#<%= BtnAllChkBox.ClientID %>').click(function ()
                {
                    if ($('input[type=checkbox]').prop("checked"))
                    {
                $('input[type=checkbox]').prop("checked", false);
                    }
                    else
                    {
                $('input[type=checkbox]').prop("checked", true);
                    }
                });
            });

    ・処理を実行した際、javascript側での処理で実行した箇所は問題なく動作します。
    ・javascript側でチェックボックス全てのcheckedプロパティの値をtrueに変更します。
    ・その後、ユーザー側で、チェックボックスのいくつかをfalseに変更します。
    ・この状態で、取得できるのは、すべてのチェックボックスのプロパティの値がtrueの状態であり、
     手動で変更したfalseの項目もtrueとして取得します。この時、表示上ではチェックボックスのチェック表示は変更しています。
     javascript側で処理を実行した後、手動でチェックボックスの値を変更した場合、どのようにcheckedプロパティの値を変更すればいいのでしょうか?

    よろしくお願いします。
    Donnerstag, 27. Januar 2022 06:52

Alle Antworten

  • 情報不足で分かりません。ごく簡単なサンプルでいいので、コピペすれば問題を再現できるコードを書いてください。
    Donnerstag, 27. Januar 2022 07:56
  • > 簡単なサンプルというのが難しく、とりあえずソースから必要な個所を抜き出してきました。

    「簡単」=「問題を再現するのに必要最低限」ということでお願いしたいのですが。

    上のコードは、肝心な部分が無いと思えば、余計なコードが多々含まれており、意味不明な部分もあったり、しかも長いということで、ちょっと読む気力が沸いてきません。

    問題を再現するのに必要最低限(あくまで必要最低限)の部分までコードを削って、と言ってもコピペすれば動くように、かつ必要な部分まで削除しないようにして、それを貼ってもらえませんか? その過程で原因が分かって自己解決できることもよくあることですし。


    • Bearbeitet SurferOnWww Freitag, 28. Januar 2022 04:27 追記&訂正
    Freitag, 28. Januar 2022 04:08
  • 上の私のレスで、

    > 問題を再現するのに必要最低限(あくまで必要最低限)の部分までコードを削って、と言ってもコピペすれば動くように、かつ必要な部分まで削除しないようにして、それを貼ってもらえませんか?

    と書きましたが、何ををしたらよいか分からないのであれば、まず以下をやって結果を連絡してください。

    (1) 最初の質問に書いてあった「javascript側でチェックボックス全てのcheckedプロパティの値をtrueに変更します。」の影響があるのか、その関係のコードを全てコメントアウトして確認。

    (2) GridView の OnDataBound="GvwBpRtrnList_DataBound", OnSelectedIndexChanged="GvwBpRtrnList_SelectedIndexChanged", OnSorting="GvwBpRtrnList_Sorting" を削除、対応するハンドラをコメントアウトしてそれらの影響を確認。

    以上の影響がなければ(依然としてダメであれば)、そこはそのままコメントアウトしておいて、一番怪しそうな CheckBox を動的に追加しているタイミングの問題、Session の使い方の問題を調べてみてください。

    可能であれば、動的に追加しないで GridView にテンプレート列を追加してその中に CheckBox を静的に配置してみてください。
    Samstag, 29. Januar 2022 01:29
  • ご指摘ありがとうございます。
    貴方が仰る最低限という要綱を満たしているのかは分かりませんが、自環境にて動作チェックを行った際のソースを添付します。
    SessionやOnSelectedIndexChanged、OnSortingを削除しても問題の挙動が確認できました。
    問題のソースは他社からの提供、問い合わせということもあり、時間がかかりました。
    その点につきましてはお詫び申し上げます。
    また以前投稿した内容は読む気にならないということですので、削除させていただきました。

    TEST.aspx
    <div>
        <asp:Button ID="BtnAllChkBox" runat="server" Text="✓" CssClass="btn btn-primary float-right" OnClientClick='return false;'/>
        <asp:Button ID="BtnGet" runat="server" Text="チェック確認" CssClass="btn btn-primary float-right" OnClick='BtnGet_Click' />
    </div>
    <div>
        <asp:GridView ID="TestGridView" runat="server" OnRowDataBound="TestGridView_RowDataBound" >
        </asp:GridView>
    </div>
    <script type="text/javascript">
        $(function ()
        {
            $('#<%= BtnAllChkBox.ClientID %>').click(function ()
            {
                if ($('input[type=checkbox]').prop("checked"))
                {
                    $('input[type=checkbox]').prop("checked", false);
                }
                else
                {
                    $('input[type=checkbox]').prop("checked", true);
                }
            });
        });
    </script>

    TEST.aspx.cs
    protected CheckBox[] CkbItem = new CheckBox[10];
    int CHBMax = 10;

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            // DataTable定義
            DataTable dt = new DataTable();
            dt.Columns.Add("チェックボックス");
            dt.Columns.Add("通番");
            for (int i = 0; i < CHBMax; i++)
            {
                // DataTableにデータ追加
                DataRow row = dt.NewRow();
                row["チェックボックス"] = i;
                row["通番"] = i;
                dt.Rows.Add(row);
            }
            // GridViewにバインド
            this.TestGridView.DataSource = dt;
            this.TestGridView.DataBind();
        }
        else
        {
            for (int i = 0; i < CHBMax; i++)
            {
                // チェックボックス設定
                CkbItem[i] = new CheckBox
                {
                    ID = "CKB" + TestGridView.Rows[i].Cells[0].Text,
                    AutoPostBack = false
                };
                TestGridView.Rows[i].Cells[0].Controls.Add(CkbItem[i]);
            }
        }
    }
    // データバインド時にチェックボックスを作成
    protected void TestGridView_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        // GridView Data設定
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            // チェックボックス生成
            for (int i = 0; i < CHBMax; i++)
            {
                CkbItem[i] = new CheckBox
                {
                    ID = "CKB" + e.Row.Cells[0].Text,
                    AutoPostBack = false
                };
            }
            CkbItem[CHBMax - 1].Attributes.Add("onClick", "if ($(this).prop('checked')) { $(this).prop('checked', false);}");
            e.Row.Cells[0].Controls.Add(CkbItem[CHBMax - 1]);
        }
    }

    // チェック確認
    protected void BtnGet_Click(object sender, EventArgs e)
    {
        System.Diagnostics.Debug.WriteLine("チェック確認");
        // チェックされた番号を取得
        for (int i = 0; i < CHBMax; i++)
        {
            if(CkbItem[i] == null)
            {
                System.Diagnostics.Debug.WriteLine(i + " : fales");
            }
            else
            {
                System.Diagnostics.Debug.WriteLine(i + " : true");
            }
        }
    }

    となります。
    2022年1月29日 1:29のコメントにありました部分のテンプレート列にCheckBoxを追加し、挙動の確認はまだ実施できておりません。
    その点は申し訳ありません。時間を取って確認致します。
    以上、よろしくお願いします。
    Dienstag, 1. Februar 2022 02:39
  • 確認のやり方に問題があると思います。質問者さんのコードの「チェック確認」は CheckBox が null か否かを確認しているだけで、チェックが入っているか否かを確認していません。

    CkbItem[i] は null ではないので if(CkbItem[i] == null) の結果全て else に制御が飛んで System.Diagnostics.Debug.WriteLine(i + " : true"); となります。 

    チェックが入っているか否かを確認するには CkbItem[i].Checked が true か false かで判定してみてください。例えば質問者さんのコードの「チェック確認」を以下のように変更して実行し、

    // チェック確認
    protected void BtnGet_Click(object sender, EventArgs e)
    {
        System.Diagnostics.Debug.WriteLine("チェック確認");
        // チェックされた番号を取得
        for (int i = 0; i < CHBMax; i++)
        {
            if (CkbItem[i] == null)
            {
                //System.Diagnostics.Debug.WriteLine(i + " : fales");
                System.Diagnostics.Debug.WriteLine(i + " : null");
            }
            else
            {
                //System.Diagnostics.Debug.WriteLine(i + " : true");
                System.Diagnostics.Debug.WriteLine(i + " : " + CkbItem[i].Checked);
            }
        }
    }

    CheckBox を以下のように操作してから[チェック確認]ボタンをクリックすれば、



    結果は以下の通り期待したものになるはずです。

    Dienstag, 1. Februar 2022 03:56