none
DetailsViewの中に、多段階のDropDownListを配置できない RRS feed

  • 質問

  • お世話になります。
    早速の質問で恐縮です。

    DetailsViewの中に、複数の段階的なDropDownListを配置しようと思います。
    良い表現が思いつかずわかりづらいと思いますが、以下のようなソースです。

      <asp:DetailsView ID="DetailsView1" runat="server">
        <Fields>
          <asp:TemplateField HeaderText="都道府県と市町村">
            <EditItemTemplate>
              <asp:DropDownList ID="dropPref" runat="server" AutoPostBack="True" DataSourceID="sqlPref" DataTextField="PREF_NAME" DataValueField="PREF_CODE"  SelectedValue='<%# Bind("都道府県コード") %>'>
              </asp:DropDownList>
              <asp:SqlDataSource ID="sqlPref" runat="server" ConnectionString="<%$ ***** %>"
                SelectCommand="SELECT [PREF_CODE], [PREF_NAME] FROM [PREFECTURE] ORDER BY 1">
              </asp:SqlDataSource>
              <asp:DropDownList ID="dropCity" runat="server" DataTextField="CITY_NAME" DataValueField="CITY_CODE" SelectedValue='<%# Bind("市町村コード") %>' DataSourceID="sqlCity">
              </asp:DropDownList>
              <asp:SqlDataSource ID="sqlCity" runat="server" ConnectionString="<%$ ***** %>"
                SelectCommand="SELECT [CITY_CODE], [CITY_NAME] FROM [CITY] WHERE ([PREF_CODE] = @PREP) ORDER BY 1">
                <SelectParameters>
                  <asp:ControlParameter ControlID="dropPref" Name="PREF" PropertyName="SelectedValue"  Type="Int32" />
                </SelectParameters>
              </asp:SqlDataSource>
            </EditItemTemplate>
            <ItemTemplate>
              <asp:Label ID="Label1" runat="server" Text='<%# Bind("都道府県名") %>'></asp:Label>
              <asp:Label ID="Label2" runat="server" Text='<%# Bind("市町村名") %>'></asp:Label>
            </ItemTemplate>
          </asp:TemplateField>
          <asp:CommandField ButtonType="Button" ShowEditButton="True" />
        </Fields>
      </asp:DetailsView>

    例えば、会員用サイトで、住所となる市町村を更新できるDetailsViewにおいて、
    「dropPref」により選択された都道府県内の市町村だけが「dropCity」に表示される仕組みです。
    dropCityのSelectedValueは、上記のとおり、会員情報が持つ市町村コードと両方向で出たバインドされています。
    そして、ここまでは無事に動作しますが、問題は、例えば
    元々「北海道 - 札幌市」だった会員が、「沖縄県 - 那覇市」にしようとした際に、dropPrefの選択後、以下のエラーメッセー画表示されてしまいます。

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

    おそらく、会員データが持つ市町村コードは札幌市のコードであるのに、沖縄県を選んだ瞬間にdropCityの中に該当する市町村コード(つまり札幌市のコード)がないためだと思われます。

    SelectedValueの値がDropDownList内になくても、無視して1つ目のアイテムを選択してくれたり出来れば良いのですが、そういった方法も見つかりませんでした。

    何らかの対策がありましたら、ご教授頂ければと思います。
    何卒よろしくお願い申し上げます。

    2006年6月21日 5:23

回答

すべての返信

  • これ、簡単にはいきそうにないですね。

    市町村のドロップダウンリストの先頭にコード0の「選択してください」なんていうデータを表示するようにしておいて、都道府県のドロップダウンリストが変更されてポストバックが起きたときには市町村のデータを0に書き換える、というようなコーディングが必要かな、と思います。
    またこのようなコーディングを行った場合、市町村のデータが0のときにはエラーにするとかのチェックも必要になりますね。

    考えてみただけで試してないので、うまくいくかどうかわかりませんが。

     

    2006年6月21日 5:38
  • お返事ありがとうございます。

    都道府県のDropDownListのSelectedIndexChangeイベントで、

      protected void dropPref_SelectedIndexChanged(object sender, EventArgs e)
      {
        DropDownList _dropCity = (DropDownList)DetailsView1.FindControl("dropCity");
        _dropCity.Items.Insert(0, new ListItem("-", "0"));
        _dropCity.SelectedValue = "0";
      }

    としてみましたが、やはり同様のエラーで引っかかります。
    うーん、DetailsView・・・巷で言われているように融通効きませんね・・・。

    別の方法を模索してみます。
    DetailsViewやFormViewのクセみたいのが未だ掴みきれていなかったので、
    もし簡単に出来るなら良いと思っていた次第です。
    難しいという事が分かっただけでも助かりました。どうもありがとうございました。


    2006年6月21日 8:17
  • > 都道府県のDropDownListのSelectedIndexChangeイベントで、

    これ、ちゃんとイベントとれてます?
    DetailsView等の中に入っているコントロールのイベントって単純にはいかなかったと思います。

    > うーん、DetailsView・・・巷で言われているように融通効きませんね・・・。

    複合的なコントロールはある使い方を想定したうえで作成されているものですから、その使い方にのっとってないことをやろうとすると難易度がいきなりあがりますね。
    仕方ないとも思いますけど。

    2006年6月21日 9:48
  • > これ、ちゃんとイベントとれてます?
    > DetailsView等の中に入っているコントロールのイベントって単純にはいかなかったと思います。
    >
    市町村DropDownListのSelectedValueを解除するとちゃんと動作(1行目に「-」が入る)するので、動いているようです。

    > 複合的なコントロールはある使い方を想定したうえで作成されているものですから、
    > その使い方にのっとってないことをやろうとすると難易度がいきなりあがりますね。
    > 仕方ないとも思いますけど。
    >
    なるほど、場面によって使い分けるんですね。
    やはり単純なフォームにだけ使うようにします。

    2006年6月22日 2:58
  • @ITのほうでも同じ質問があがったのでなんとか実現する方法がないか試してみました。
    少しプログラムを記述することで実装できました。

    http://dotnetfan.org/blogs/dotnetfanblog/articles/737.aspx

     

    2006年7月9日 18:06
  • 普通に

    データソースを複数用意して

    where 条件のところで条件設定して 複数ドロップダウンリストを作ればいいだけでしょが・・・・・

     

    aのドロップダウンをつくってそのドロップダウンのデータを参照すればいいだけ。

    めちゃかんたんでしょうが。

    あと

    参照側には更新側のデータは全部ないと みつかりませんというエラーでるよ。

    参照側 a b c d e f g  更新側 a c d みたいな感じ。

    参照側に全部データ追加して、distinctでみるというのもあり。

    とにかくない更新データはサマリーして参照側と比較して追加。

    2011年6月23日 19:49