0

ASP.NETウィザードコントロールがあります。2番目のステップでは、2つのリストボックスがあります。ページが読み込まれると、最初のListBoxアイテムがサーバーから入力されます。

次に、ユーザーはListBox1からデータを選択し、それをListBox2に移動します。次に、ユーザーはウィザードの[次へ]ボタンをクリックします。どういうわけか、ユーザーが[次へ]をクリックすると、ListBox2は空になります。

jQueryを使用してデータをListBox1からListBox2に移動します。

<td class="style9">
                <asp:ListBox ID="registerCompCats" runat="server" CssClass="ListBox1"
                ClientIDMode="Static" DataTextField="value" DataValueField="key"
                Rows="5" size="5" style="width:135px; size:5px;" SelectionMode="Multiple" ></asp:ListBox>
                    &nbsp;&nbsp;&nbsp;</td>
                <td class="style1">
                    <table>
                        <tr>
                            <td style="padding-left: 20px;">
                                <img id="addCat" onclick="return addCat_onclick()" 
                        src="images/buttons/btn_addCat.jpg" title="Add Category" />
                            </td>
                        </tr>
                        <tr>
                            <td style="padding-left: 20px;">
                                <img id="removeCat" 
                        src="images/buttons/btn_removeCat.jpg" title="Remove Category" />
                            </td>
                        </tr>
                    </table>
                </td>
                <td>
                <asp:ListBox ID="registerCompAcats" runat="server" CssClass="ListBox2"
                ClientIDMode="Static" DataTextField="value" DataValueField="key"
                Rows="5" size="5" style="width:135px; size:5px; margin-top: 0px;" SelectionMode="Multiple" ></asp:ListBox>
                    &nbsp;<asp:RequiredFieldValidator ID="registerCompAcatsValidator" runat="server" 
                        ControlToValidate="registerCompAcats" Display="None" ErrorMessage="categories"></asp:RequiredFieldValidator></td>
4

1 に答える 1

3

イベントの検証

リストボックスやドロップダウンリストの利用可能なオプションをクライアント側(つまり、jQueryなど)でねじ込むと、組み込みのASP .NETフォーム検証(「イベント検証」と呼ばれる)が開始され、例外は、最初にコントロールをレンダリングしたときに指定したものとは異なるオプションを使用してフォームを送信しているためです。これを回避するには、.aspxページの上部でこれを行う必要があります。

<%@ Page EnableEventValidation="false" %>

これを行う場合は、ドロップダウンとリストボックスでフォームの検証を自分で実行する必要があることに注意してください。

ビューステート

ページがサーバーにポストバックされるたびに、これらのコントロールには0の選択肢があります。はい、HTMLに選択肢が表示されますが、サーバーでは、選択肢が0であることが最初に表示されます。これらのコントロールでビューステートを有効にしている場合、前のページレンダリングに存在していた選択肢は、ページのライフサイクル中にASP.NETフレームワークによって自動的に追加されます。これはregisterCompAcats、最初のページのレンダリングでコントロールに選択肢がなかったため、ページがサーバーにポストバックされたときに、まだ選択肢がないことを意味します。

これらのコントロールは、HTMLの要素asp:ListBoxとしてレンダリングされます。<select>これらが機能する方法は、これらのリストボックスで選択された値だけをサーバーに送信することです。つまり、選択肢が何であっても、フォーム投稿のこれらのリストボックスでユーザーが選択したアイテムについてのみ知ることができます。

可能な解決策

この問題を解決するには、いくつかのアプローチがあります。いくつかの概要を説明します。

アプローチ1:他のリストボックスにアイテムを追加するためのポストバック

これはおそらく最も単純ですが、最も効率的ではありません。ユーザーが[カテゴリの追加]ボタンをクリックするたびに、jQueryを使用してアイテムをあるリストボックスから別のリストボックスに移動するのではなく、ページのポストバックが発生する可能性があります。これにより、サーバー側のコードで各ボックスに表示される選択肢を制御でき、ビューステートが有利に機能します。ページでイベント検証を再度有効にすることもできます。これは一般的には良い考えです。

<asp:ListBox id="lb1" runat="server" />
<asp:Button id="btnAdd" runat="server" />
<asp:ListBox id="lb2" runat="server" />

btnAdd.Clickイベントの場合:

Sub btnAdd_Click(sender As Object, args As EventArgs) Handles btnAdd.Click

  lb2.Items.AddRange(lb1.Items.Where(Function(i) i.Selected).ToArray())

End Sub

アプローチ2:jQueryを使用してアイテムを追加します。投稿する前に投稿を操作する

上で説明したように、これにはイベント検証をオフにする必要があります。jQueryを使用して、アイテムをあるリストから別のリストに移動します。これで問題ありません。ただし、実際にページにポストバックを発生させる前に、jQueryを使用して2番目のリストボックスのすべての値を収集し、それらの値を。である非表示フィールドに配置しますrunat="server"

<asp:ListBox id="lb1" runat="server" />
<input type="button" value="Add" onclick="addCategory();" />
<asp:ListBox id="lb2" runat="server" />
<input type="hidden" id="hdnSelectedCategories" runat="server" />
<asp:Button id="btnSubmit" runat="server" onclientclick="preSubmit();" />

jQueryの部分:

<script type="text/javascript">

  var lb1, lb2, hdnSelectedCategories;

  $(function() {
    lb1 = $('#<%=lb1.ClientID %>');
    lb2 = $('#<%=lb2.ClientID %>');
    hdnSelectedCategories = $('#<%=hdnSelectedCategories.ClientID %>');
  });

  function addCategory() {
    lb2.append(lb1.find('option:selected'));
  }

  function preSubmit() {
    // collect all the values from the lb2 listbox into an array
    var values = [];
    lb2.find('option').each(function(index, item) {
      values.push($(item).val());
    });
    // now put the contents of the array in the hidden input, separated by commas
    hdnSelectedCategories.val(values.join(','));
  }
</script>

btnSubmit.Clickイベントのコードビハインドでは、次のようになります。

Sub btnSubmit_Click(sender As Object, args As EventArgs) Handles btnSubmit.Click

  Dim values As String() = hdnSelectedCategories.Value.Split(",")

  'TODO: Profit'

End Sub

このアプローチでは、リストボックスのビューステートをオフにすることもできます。これは、リクエストに肥大化を追加し、ユーザーが[送信]ボタンをクリックした後にリストボックスをリセットするためです。

免責事項

私はこのコードを最小限にテストしました-それは私の頭のすぐ上にあります。ただし、イベントの検証、ビューステート、およびポストバックページのライフサイクルの説明が、実際に何が起こっているのかを理解するのに役立ち、状況に合ったソリューションを考え出すことができれば幸いです。

于 2012-10-11T13:16:48.760 に答える