質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.12%

SqlDataSourceの処理実行タイミング

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 2,519

makao

score 10

質問内容

・SqlDataSourceの実行されるタイミングについて

発生している問題

DropDownlistをPage_LoadでSelectedIndexしようとしているが
まだ中身が生成されていないらしくFindByValueであるべきItemが見つからない。

該当のソースコード

<asp:DropDownList ID="DropDown1" runat="server"  style="vertical-align: middle;"  DataSourceID="SqlDataSource1" DataTextField="名称" DataValueField="区分" AppendDataBoundItems="true">
    <asp:ListItem Value="" Text="" />
</asp:DropDownList>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:AAAConnectionString %>" SelectCommand="SELECT [区分], [名称] FROM [マスタテーブル] WHERE ([有効FLG] = @有効FLG) ORDER BY [区分]">
    <SelectParameters>
        <asp:Parameter DefaultValue="true" Name="有効FLG" Type="Boolean" />
    </SelectParameters>
</asp:SqlDataSource>

c#
protected void Page_Load(object sender, EventArgs e){

//reader=command.ExecuteReader() テーブルから対象レコード1件取得(区分はマスタテーブルに存在するもの)
li = DropDown1.Items.FindByValue(reader["区分"].ToString());
i = DropDown1.Items.IndexOf(li);
DropDown1.SelectedIndex = i;
}

補足情報(言語/FW/ツール等のバージョンなど)

html書き直し等できないため処理実行のイベントタイミングの変更で対応したい

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

Page_Load の時点では、質問者さんの言われるとおり、DropDownList にデータバインドされていませんので、Page_load ではなく DropDownList.DataBound イベントのハンドラで設定すればうまくいくのではないかと思います。

お試しください。ダメならその旨連絡ください。実際にコードを書いて検証してみます。

【2016/10/6 10:50 追記】

私の 2016/10/06 10:24 のコメントで「具体例はあとで回答欄に追記しておきます」と書きましたように、すべて Page.Load イベントで行う例を書いておきます。データベースは Microsoft が提供しているサンプルデータベース Northwind の Employees テーブルを使っています。Button はポストバックした時の動作の確認用です。

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

    // 2016/10/5 teratail の検証用
    // https://teratail.com/questions/50422

    protected void DropDownList1_DataBound(object sender, EventArgs e)
    {
        // EmployeeID = 7 の LastName は King
        //ListItem item = DropDownList1.Items.FindByValue("7");
        //int index = DropDownList1.Items.IndexOf(item);
        //DropDownList1.SelectedIndex = index; 
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            DropDownList1.DataSource = 
                (DataView)SqlDataSource1.Select(DataSourceSelectArguments.Empty);
            DropDownList1.DataBind();

            // EmployeeID = 7 の LastName は King
            ListItem item = DropDownList1.Items.FindByValue("7");
            int index = DropDownList1.Items.IndexOf(item);
            DropDownList1.SelectedIndex = index; 
        }        
    }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
            ConnectionString="<%$ ConnectionStrings:NORTHWINDConnectionString %>" 
            SelectCommand="SELECT [EmployeeID], [LastName] FROM [Employees]">
        </asp:SqlDataSource>
        <asp:DropDownList ID="DropDownList1" runat="server" 
            DataTextField="LastName" 
            DataValueField="EmployeeID" OnDataBound="DropDownList1_DataBound">
        </asp:DropDownList>
        <asp:Button ID="Button1" runat="server" Text="Button" />
    </form>
</body>
</html>

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/06 10:39 編集

    >デフォルトで(DataSourceMode プロパティが DataSet)データを DataSet オブジェ>クトに読み込み、サーバー上のメモリに格納するのですが
    規約によりコーディングに制限があります。
    (なぜだかよくわかりませんが)DBのデータを使う場合、そのイベント内で毎度取得に行かねばならず、DropDownListがあるだけ毎度毎度コネクションをはって取得にいくロジックを書かねばなりません(個人的にはメンテしにくいだけだと思うのですが)
    Page_Loadに拘っているのではなくHTMLをなかなか直させてくれないので
    なので全DropDownListの中身が入っている状態のイベント1つのスコープ内で一度だけDBアクセスし、全DropDownListのSelectedIndexを操作する方向で話をもっていければと。

    キャンセル

  • 2016/10/06 10:55

    依然として「スコープ」等の意味が理解できていませんが、とりあえず Page_Load 内で設定する例を回答欄に書いておきました。これでも NG なら具体的にその理由を連絡ください。

    キャンセル

  • 2016/10/06 10:58 編集

    ご教示いただいた方法で実装できそうです。
    サンプルまで用意いただけるとは大変恐縮、尽力感謝!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.12%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる