none
FormViewで2つの連動するDropDownListで、プルダウン選択肢が増幅します。 RRS feed

  • 質問

  • FormViewで顧客情報を入力するフォーム画面を作成しております。
    フォーム内に、「学年」「組」という2つの連動するDropDownListを配置しました。
    うまく動きませんでした。

    例)
    ・1度目「学年」で「1年生」を選ぶと、AutoPostBackで「組」を「1,2,3,4組」を正常に選べます。
    ・2度目「学年」で「2年生」を選ぶと、AutoPostBackで「組」を「1,2,3,4,1,2,3,4組」とプルダウンが増幅します。
    ・3度目「学年」で「3年生」を選ぶと、AutoPostBackで「組」を「1,2,3,4,1,2,3,4,1,2,3,4組」とプルダウンが増幅します。

    ご教授頂けないでしょうか。
    以下はプルダウンのDBとなります。

    -----------------------
    ▼学校情報テーブル(School)
    学校ID:SchoolId (1,2,3などのIDデータ)
    学校名:SchoolName (ABC高等学校などのデータ)
    学級年度:SchoolYear (2010,2011,2012などの年度データ)

    ▼学校クラス情報テーブル(SchoolClass)
    クラスID:SchoolClassId (1,2,3などのIDデータ)
    年:SchoolClassYear (1,2,3年などのデータ)
    組:SchoolClassName (1,2,3,4組などのデータ)
    学校ID:SchoolId(FK)
    -----------------------

    以下はソースとなります。
    ------------------------------------------------------
                <tr><th>学年</th>
                <td>
                    <asp:SqlDataSource ID="StudentSchoolClassYearSqlDataSource"
                        runat="server"
                        ConnectionString="~~~"
               SelectCommand="SELECT DISTINCT SchoolClassYear FROM SchoolClass
                             INNER JOIN School
                              ON SchoolClass.SchoolId = School.SchoolId
                             WHERE (School.SchoolName = @SchoolName)
                             AND   (School.SchoolYear = @SchoolYear)
                             ORDER BY SchoolClassYear ASC">
                    <SelectParameters>
                 <asp:SessionParameter DefaultValue="" Name="SchoolName" SessionField="SchoolName" Type="string" />
                 <asp:SessionParameter DefaultValue="" Name="SchoolYear" SessionField="SchoolYear" Type="Int32" />
                    </SelectParameters>
                    </asp:SqlDataSource>
                    <asp:DropDownList ID="StudentSchoolClassYearDropDownList"
                        AutoPostBack="True"
                        runat="server"
                        DataSourceID="StudentSchoolClassYearSqlDataSource"
                        DataTextField="SchoolClassYear"
                        DataValueField="SchoolClassYear"
                        AppendDataBoundItems="True"
                        SelectedValue='<%# Bind("StudentSchoolClassYear") %>'>
                        <asp:ListItem Selected="True" Value ="" Text="未選択">未選択</asp:ListItem>
                    </asp:DropDownList><br></td></tr>

                <tr><th>組</th>
                <td>
                    <asp:SqlDataSource ID="StudentSchoolClassNameSqlDataSource"
                        runat="server"
                        ConnectionString="~~~"
               SelectCommand="SELECT DISTINCT SchoolClassName FROM SchoolClass
                             INNER JOIN School
                              ON SchoolClass.SchoolId = School.SchoolId
                             WHERE (School.SchoolName = @SchoolName)
                                AND   (School.SchoolYear=@SchoolYear)
                                AND   (SchoolClass.SchoolClassYear=@StudentSchoolClassYearDropDownList)
                             ORDER BY SchoolClassName ASC">
                    <SelectParameters>
                 <asp:ControlParameter ControlID="StudentSchoolClassYearDropDownList" Name="StudentSchoolClassYearDropDownList" PropertyName="SelectedValue" />
                 <asp:SessionParameter DefaultValue="" Name="SchoolName" SessionField="SchoolName" Type="string" />
                 <asp:SessionParameter DefaultValue="" Name="SchoolYear" SessionField="SchoolYear" Type="Int32" />
                    </SelectParameters>
                    </asp:SqlDataSource>
                    <asp:DropDownList ID="StudentSchoolClassNameDropDownList"
                        runat="server"
                        DataSourceID="StudentSchoolClassNameSqlDataSource"
                        DataTextField="SchoolClassName"
                        DataValueField="SchoolClassName"
                        AppendDataBoundItems="True"
                        <asp:ListItem Selected="True" Value ="" Text="未選択">未選択</asp:ListItem>
                    </asp:DropDownList><br></td></tr>
    ------------------------------------------------------

    すいません。
    どこがおかしいのかも分からない状態です。
    何か解決方法はありますでしょうか?

    2012年6月11日 10:13

回答

  • 2 つ目の DropDownList の ViewState を無効にすれば(EnableViewState="False" と
    設定する)、うまくいくと思います。

    #スレッドが乱立気味です。もう少しよく考えてからスレッドを立てていただければ
     と思います。

    • 回答としてマーク ミルズ 2012年6月18日 5:52
    2012年6月11日 13:39

すべての返信

  • AppendDataBoundItems="True"

    ということで、PostBackの発生都度、アイテムが追加されていきますね。
    未選択のアイテムが必要なければこの設定変更するだけで動くように思います。

    どうしても未選択のアイテムも必要、ということだと。。。
    DataBindが発生してから、となるとStudentSchoolClassYearDropDownListの
    PreRenderイベントあたりでアイテムの先頭に未選択のListItemのインスタンスを
    追加してあげるのがいいかな。


    あおい情報システム株式会社 小野修司(どっとねっとふぁん)

    2012年6月11日 10:39
  • 2 つ目の DropDownList の ViewState を無効にすれば(EnableViewState="False" と
    設定する)、うまくいくと思います。

    #スレッドが乱立気味です。もう少しよく考えてからスレッドを立てていただければ
     と思います。

    • 回答としてマーク ミルズ 2012年6月18日 5:52
    2012年6月11日 13:39
  • >SurferOnWww様

    度々のスレッドを立て申し訳ございません。

    納期間際ということもあって大変申し訳ございませんでした。

    ------------------------------------------

    「組」のプルダウンを以下のように修正しました。

    ・「AppendDataBoundItems="True"」を追記。

    ・「EnableViewState="False"」を追記。

    --------------------------------------------------------------------------

    <asp:DropDownList ID="StudentSchoolClassNameDropDownList"
                        runat="server"
                        DataSourceID="StudentSchoolClassNameSqlDataSource"
                        DataTextField="SchoolClassName"
                        DataValueField="SchoolClassName"
                        AppendDataBoundItems="True"
                        <asp:ListItem Selected="True" Value ="" Text="未選択">未選択</asp:ListItem>

    --------------------------------------------------------------------------

    「組」が「1,2,3,4,1,2,3,4,1,2,3,4組」のようにプルダウンが増幅する。

    という事は解決いたしました。

    しかし、DBにプルダウン選択した値「4(組)」などのデータが格納されませんでした。。。

    自分なりに試して、「SelectedValue='<%# Bind("StudentSchoolClassName") %>'>」が必要なのでは。と考えてみましたが、

    その際は以下のようなエラーとなりました。

    「Eval()、XPath()、および Bind() のようなデータバインド メソッドは、データバインドされたコントロールのコンテキストでのみ使用することができます。」

    というエラーになります。

    あとはInsertParametersやUpdateParametersを工夫はしてみましたが、

    DBに値が格納されない。あるいはエラーが解決できませんでした。

    度々で申し訳ございません。

    お力添え頂けないでしょうか。

    2012年6月12日 0:51
  • 現在、このスレッドに提示されているコードはいずれもDropDownListの部分のみであり、これらDropDownListで選択した値をデータベースへ保存するコードが見当たりません。データベースへ保存するコードはどのように書かれていますか?


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    2012年6月12日 1:16
    モデレータ
  • 以下ソースとなります。
    基本的にFormViewを配置してから、ソースはそのままです。

    ※余計そうな項目は抜粋させて頂きました。(生徒ID,氏名(姓)、氏名(名)、学年、組が項目となります)
    ※Delete処理(削除ボタン)は使用していないので、Delete文は抜粋させて頂きました。

    DBに格納するにはパラメータ[StudentSchoolClassName]に手を加える必要があるのでは?!
    と疑ってはいるのですが。
    どうぞ宜しくお願いいたします。

    -------------------------------------------------
        <asp:SqlDataSource ID="SqlDataSource1" runat="server"
            ConflictDetection="CompareAllValues"
            ConnectionString="<%$ ConnectionStrings:xyzConnectionString %>"
           
            InsertCommand="INSERT INTO [Student]
             ([StudentId], [StudentNameSei], [StudentNameMei],
             [StudentSchoolClassYear], [StudentSchoolClassName], ~その他の項目~)
            VALUES (@StudentId, @StudentNameSei, @StudentNameMei,
             @StudentSchoolClassYear,@StudentSchoolClassName, ~その他の項目~)"
            OldValuesParameterFormatString="original_{0}"

            SelectCommand="SELECT * FROM [Student] WHERE ([StudentId] = @StudentId)"
           
            UpdateCommand="UPDATE [Student] SET [StudentNameSei] = @StudentNameSei,
             [StudentNameMei] = @StudentNameMei,
             [StudentSchoolClassYear] = @StudentSchoolClassYear,
             [StudentSchoolClassName] = @StudentSchoolClassName, 
             ~その他の項目~
             WHERE
              [StudentId] = @original_StudentId
              AND (([StudentNameSei] = @original_StudentNameSei) OR ([StudentNameSei] IS NULL
              AND @original_StudentNameSei IS NULL))
              AND (([StudentNameMei] = @original_StudentNameMei) OR ([StudentNameMei] IS NULL
              AND @original_StudentNameMei IS NULL))
              AND (([StudentSchoolClassYear] = @original_StudentSchoolClassYear) OR ([StudentSchoolClassYear] IS NULL
              AND @original_StudentSchoolClassYear IS NULL))
              AND (([StudentSchoolClassName] = @original_StudentSchoolClassName) OR ([StudentSchoolClassName] IS NULL
              AND @original_StudentSchoolClassName IS NULL))
              ~その他の項目~">
           
            <InsertParameters>
                <asp:Parameter Name="StudentId" Type="Int32" />
                <asp:Parameter Name="StudentNameSei" Type="String" />
                <asp:Parameter Name="StudentNameMei" Type="String" />
                <asp:Parameter Name="StudentSchoolClassYear" Type="Int32" />
                <asp:Parameter Name="StudentSchoolClassName" Type="Byte" />
                ~その他の項目~
            </InsertParameters>
           
            <SelectParameters>
                <asp:QueryStringParameter Name="StudentId" QueryStringField="StudentId"
                    Type="Int32" />
            </SelectParameters>
           
            <UpdateParameters>
                <asp:Parameter Name="StudentNameSei" Type="String" />
                <asp:Parameter Name="StudentNameMei" Type="String" />
                <asp:Parameter Name="StudentSchoolClassYear" Type="Int32" />
                <asp:Parameter Name="StudentSchoolClassName" Type="Byte" />
                ~その他の項目~
            </UpdateParameters>
           
        </asp:SqlDataSource>
    -------------------------------------------------

     

    2012年6月12日 1:46
  • DropDownListで選択した値をSqlDataSource1のUpdateParametersに渡す必要があります。SqlDataSource1のプロパティからUpdateQueryを設定する画面を開き、そこで「パラメータソース」を「Control」とし、「ControlID」をStudentSchoolClassYearDropDownListなどと設定してみて下さい。

    (参考)
    データ ソース コントロールとパラメータの使用
    http://msdn.microsoft.com/ja-jp/library/xt50s8kz(v=vs.90).aspx


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    2012年6月12日 3:04
    モデレータ
  • ご指摘いただいた内容で色々と試してみました。
    なかなかうまくいかず、エラー画面が表示されたり、
    「組」の値が正常に登録できなかったりと。して。
    行き詰っております。

    以下、試した内容になります。
    アドバイス頂けないでしょうか。

    -------------------------------------------------------

    <asp:ControlParameter ControlID="FormView1" Name="SchoolClassName" PropertyName="SelectedValue" Type="Int32"/>
    Insert/Updateの結果:エラー
    System.Data.SqlClient.SqlException: スカラー変数 "@StudentSchoolClassName" を宣言してください。

    -------------------------------------------------------

    <asp:ControlParameter ControlID="FormView1" Name="StudentSchoolClassName" PropertyName="SelectedValue" Type="Int32"/>
    Insertの結果:DB登録は完了するが、[StudentSchoolClassName]の値がNULLとなる。
    Updateの結果:DB登録は完了するが、[StudentSchoolClassName]の値が[StudentId(主キーです)]が格納される。
    (※個人的な見解なのですが、上記の場合はFormViewの1番目のフィールドの値がDBに格納されるのでは???と思いました。)

    -------------------------------------------------------
    ▼SelectedDataKeyをNameで指定してみた。
    <asp:ControlParameter ControlID="FormView1" Name="StudentSchoolClassName" PropertyName='SelectedDataKey["StudentSchoolClassName"]' Type="Int32"/>
    Insert/Updateの結果:エラー
    System.Web.HttpException: DataBinding: 'System.Web.UI.WebControls.FormView' には SelectedDataKey という名前のプロパティは含まれません。

    -------------------------------------------------------
    ▼SelectedDataKeyを配列番号で指定してみた。
    <asp:ControlParameter ControlID="FormView1" Name="StudentSchoolClassName" PropertyName="SelectedDataKey[7]" Type="Int32"/>
    Insert/Updateの結果:エラー
    System.Web.HttpException: DataBinding: 'System.Web.UI.WebControls.FormView' には SelectedDataKey という名前のプロパティは含まれません。

    -------------------------------------------------------
    ▼SelectedDataKey.ValuesをNameで配列番号してみた。
    <asp:ControlParameter ControlID="FormView1" Name="StudentSchoolClassName" PropertyName="SelectedDataKey.Values[7]" Type="Int32"/>
    Insert/Updateの結果:エラー
    System.Web.HttpException: DataBinding: 'System.Web.UI.WebControls.FormView' には SelectedDataKey という名前のプロパティは含まれません。

    -------------------------------------------------------
    ▼SelectedDataKey.ValuesをNameで指定してみた。
    <asp:ControlParameter ControlID="FormView1" Name="StudentSchoolClassName" PropertyName='SelectedDataKey.Values["StudentSchoolClassName"]' Type="Int32"/>
    Insert/Updateの結果:エラー
    System.Web.HttpException: DataBinding: 'System.Web.UI.WebControls.FormView' には SelectedDataKey という名前のプロパティは含まれません。

    -------------------------------------------------------
    ▼あとは、以下のようにFormViewタグのDataKeyNamesに[StudentSchoolClassName]を指定してみた。
    <asp:FormView ID="FormView1" runat="server" DataKeyNames="StudentId,StudentSchoolClassName" DataSourceID="SqlDataSource1" CellPadding="0" DefaultMode="Edit" ForeColor="White">
    Insert/Updateの結果:エラー
    System.Web.HttpException: DataBinding: 'System.Web.UI.WebControls.FormView' には SelectedDataKey という名前のプロパティは含まれません。

    2012年6月12日 8:12
  • > 自分なりに試して、「SelectedValue='<%# Bind("StudentSchoolClassName")
    >  %>'>」
    > が必要なのでは。と考えてみましたが、その際は以下のようなエラーとなりました。
    >
    >
    > 「Eval()、XPath()、および Bind() のようなデータバインド メソッドは、データ
    > バインドされたコントロールのコンテキストでのみ使用することができます。」
    >
    > というエラーになります。

    DropDownList が一つだけとか、二つあっても連動してない場合はそ
    れでいけますが、連動しているとダメです。

    エラーメッセージからすると、以下のページに書いてあることが原因
    と思われます。DetailsView の例ですが FormView でも同じ問題が出
    ます。対処方法も書いてあるので見てください。

    DetailsView 中の連動 DropDownList
    http://surferonwww.info/BlogEngine/post/2010/12/04/Dual-DropDownLists-in-DetailsView.aspx

    エラーメッセージでググると、他にも参考になりそうなページが見つか
    ると思います。


    なお、表題と違うことを質問する場合は、新たに別のスレッドを立てて
    質問するようにしてください。(同様な質問を持つ人が、検索でここに
    たどり着いた時に、表題と中身が一致しているということは重要です)

    また、次から次へと質問するのではなくて、質問する前に、自分で解決
    するための努力(エラーメッセージでググって調べるなど)をしていた
    だければと思います。

    2012年6月12日 12:24
  • 色々と試したのですが、解決には至りませんでした。

    ずっとスレッドを残すのもよくないので、クローズとさせて頂きます。

    アドバイスを頂きありがとうございました。

    2012年6月18日 5:51