- PR -

動的コントロール(ドロップダウンリスト等)の選択値取得

1
投稿者投稿内容
にゃんこ
会議室デビュー日: 2003/02/04
投稿数: 4
投稿日時: 2003-02-13 16:25
初めて投稿させていただきます。よろしくお願いいたします。
現在ASP.Net(C#)で以下の動作を実装したいと思っています。

実装したい動作:
「プログラムによって動的に作成したコントロール(ドロップダウンリスト)
 で選択された値を取得したい。」


現在までに、パネルコントロールをコンテナとし、
 ・ラベルコントロール:1個
=>TEXT、IDプロパティを設定

 ・ドロップダウンリスト:1個
=>DataSourceを生成し、DataTextField、DataValueField、IDプロパティを設定

上記を動的に作成し、表示することができました。

更にデザイナ時にボタンコントロールを1個配置しております。

ボタン押下時にドロップダウンリストの選択値(SelectedItem.Value)を取得したいのですが
取得できません。

コンテナ内の子コントロールをIDでFindControlすればよいかと思ったのですが、
そういったメソッドがないようです。
(もしくは見つけられないようです。子コントロールでなければ可能なのですが。。。)


どなたかご存知の方がいらっしゃったら、お手数ですがご返信のほどよろしく
お願いいたします。。

もしくは、ちょっとしたヒント(可能/不可能とか)でもご指摘いただけると
うれしいです。

mito
ベテラン
会議室デビュー日: 2002/05/17
投稿数: 50
投稿日時: 2003-02-17 10:49
ボタンのクリックイベントで
単純にRequest.Params("ここにプログラムで設定したコンボのID")で取得できませんか?
注意:この場合は本当にOptionに設定したValueしか取れません。
机上の理論なのでうまくいかなかったらごめんなさい。
poteto
ベテラン
会議室デビュー日: 2002/08/08
投稿数: 50
投稿日時: 2003-02-17 11:54
こんにちは。。。
以下の方法で見つけられませんか?
コード:
private void Button1_Click(object sender, System.EventArgs e)
{
	string ddlValue = ((DropDownList)Panel1.FindControl("ddlId"))
					.SelectedItem.Value;
}


"ddlId"は、動的に指定したドロップダウンリストのID名です。
にゃんこ
会議室デビュー日: 2003/02/04
投稿数: 4
投稿日時: 2003-02-17 12:31
mitoさん、potetoさん、ありがとうございました。
お二人のおかげで解決いたしました。

コンテナ内の子コントロールをIDでFindControlができなかったのは、
動的にIDを変更しているためでした。(これは本件とは直接関係ない現象ですが・・・)
「動的にIDを変更している」というのは、ボタン押下時(ポストバック発生時)に以下のようなメッセージが表示されるためです。

・「同じID 'DropDownList1' を持つ複数のコントロールが見つかりました。FindControl を使うには、コントロールに一意の ID を指定する必要があります。 」
どうやら、IDをランダム関数か何かを用いて変更しないといけない模様です。
(あやしいな。。ほんとかな。。)

しかし、FindControlは現在表示されているコントロールをFindするもので、
以前に選択された値をドロップダウンリストに選択させてやりたいなどの場合には
mitoさんのご指摘のように「Request.Params」を使うと以前のIDでの選択値が取得できました。

よって「ドロップダウンリストに選択された値をボタン押下時にセットする」には

・以前に選択されたドロップダウンリストの値を取得する
==>mitoさんの方法で可能
 NameValueCollection coll;
 coll = Request.Params;
 String[] arr2=coll.GetValues("DDL1");

・新しいIDで表示されるドロップダウンリストへの設定
==>potetoさんのご指摘の応用して、「SelectedIndex」プロパティを使用する

((DropDownList)Panel1.FindControl("DDL21")).SelectedIndex = 1;

でできそうです!上記にちょっとびみょーですがそのコードを示してみました。

説明が長くなりましたが、本当にありがとうございました!


一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2003-02-17 17:50
すいません、横槍なんですが「動的にコントロールを作る」というのは
コード:

DropDownList DDList=new DropDownList();
DDList.ID="DDList";
DDList.Items.AddRange(new ListItem[]{new ListItem("AAA","a")
,new ListItem("BBB","b")
,new ListItem("CCC","c")});
Panel1.Controls.Add(DDList);


のようにオブジェクトを作るということですか?
それともResponse.Write()で<SELECT>タグ等を書き出すということですか?

FindControl()などの話も出ていましたのでオブジェクトを作るのだとは思いますが、そうすると「同じIDを持つ複数のコントロールが・・・」というのが分かりません。
(私がやって見た限り、ポストバックされた時にはPanelに動的に設定した子コンロトールは無くなっていましたので)

にゃんこさん、宜しければ(動的に作る部分の)ソースを教えて頂けませんでしょうか。

[ メッセージ編集済み 編集者: 一郎 編集日時 2003-02-17 17:52 ]
にゃんこ
会議室デビュー日: 2003/02/04
投稿数: 4
投稿日時: 2003-02-17 18:56
正しいかどうかわかりませんが、サンプル的なものでいいでしょうか?

「同じIDを持つ複数のコントロールが・・・」というのは、下記のサンプルコードで
 ・ mylabel.ID = "Label" + iID.ToString();

の部分で「iID」をランダムに変更しなければ現象を確認できると思います。
(int iID = Int32.Parse(ViewState["COUNT"].ToString());の部分で色々と値を変更しております。VB.NETならRand()関数等用いればViewStateなど使わずに、もっと簡単にできると思います。)
どういうわけか、一度使用したIDがPostBack時に残っているようなのでIDをランダムに変更しました。



private void Page_Load(object sender, System.EventArgs e)
{
 if (!Page.IsPostBack)
 {
  ViewState["COUNT"]=1;
 }else{
  int iCount = Int32.Parse(ViewState["COUNT"].ToString());
  iCount +=10;
  ViewState["COUNT"] = iCount.ToString() ;
  Panel1.Controls.Clear();
}

int iID = Int32.Parse(ViewState["COUNT"].ToString());

for (int i=0; i<3; i++)
{
//ラベル追加
Label mylabel =new Label();
mylabel.Text = "Label" + iID.ToString();
mylabel.ID = "Label" + iID.ToString();
Panel1.Controls.Add (mylabel);

//スペース追加
Panel1.Controls.Add(new LiteralControl("&nbsp;&nbsp;&nbsp;"));
iID += 1 ;
}
}
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2003-02-18 13:26
にゃんこさん。

ViewState["COUNT"]をポストバックに関係なく1に設定したり
Panel1.Controls.Clear()
を実行してみたりしなかったりとやってみたのですが、
Panel1.FindControl()
は問題なく実行できてしまいました。

後、関連した話ですが、Page_Load()に
コード:
if(!this.IsPostBack)
{
    DropDownList DDList=new DropDownList();
    DDList.ID="DDList";
    DDList.Items.AddRange(new ListItem[]{new ListItem("AAA","a")
                                        ,new ListItem("BBB","b")
                                        ,new ListItem("CCC","c")});
    Panel1.Controls.Add(DDList);
}
else
{
    DropDownList DDList=new DropDownList();
    DDList.ID="DDList";
    DDList.Items.AddRange(new ListItem[]{new ListItem("XXX","a")
                                        ,new ListItem("YYY","b")
                                        ,new ListItem("ZZZ","c")});
    Panel1.Controls.Add(DDList);

    Label1.Text=DDList.SelectedItem.Text;
}

のようにした場合に、BBBを選んでポストバックさせると、Label1には"XXX"が表示されるのですが、表示したDropDownListはYYYが選ばれています。
ListItemのValueが等しい場合のみ起こります。

危険な動きですね。コントロールオブジェクトをコード内で動的に作って表示するというのはあまり良くないのかな。
にゃんこ
会議室デビュー日: 2003/02/04
投稿数: 4
投稿日時: 2003-02-19 15:26
一郎さん。調査していただいてありがとうございました。
リプライ遅れてすみません。

ViewState["COUNT"]をポストバックに関係なく1に設定したり
Panel1.Controls.Clear()
を実行してみたりしなかったりとやってみたのですが、
Panel1.FindControl()
は問題なく実行できてしまいました。
==>
どうやら私の環境でのみ発生している現象みたいです。。
(他のマシンでソースを渡して実行してもらいました。。)

危険な動きですね。コントロールオブジェクトをコード内で動的に作って表示するというのはあまり良くないのかな
==>
そうなのかもしれませんね。。。ううっ。。

私ももうちょっと調べてみます。。何かわかりましたらまた
ご連絡しますね ^^

でもみなさんのおかげで色々わかってきました。
ありがとうございました。
またよろしくお願いします!!








1

スキルアップ/キャリアアップ(JOB@IT)