none
テーブルのセルにHyperLinkFieldカラムを含むGridViewを動的に追加する方法 RRS feed

  • 質問

  • テーブルオブジェクトの1つのセルの中に、プログラム上で生成したGridView
    コントロールを入れたいと考えております。
    DataTableにカラム(String型)を定義し、データ行をセットしました。
    次に、GridViewのインスタンスを生成し、上記のDataTableをDataSource
    としてBindしました。
    冒頭のセルにコントロール追加で先のGridViewオブジェクトを追加し、無事に
    セル内にGridViewを表示させることができました。

    ここからが問題なのですが、実はGridViewの中にHyperLinkFieldを入れたい
    と思い、DataTableのカラム定義をStringからHyperLinkFieldに変更したの
    ですが、DataBind()の箇所で、

    「GridView のデータ ソースは列を生成するプロパティまたは属性を含んで
    いません。データ ソースがコンテンツを含んでいることを確認してください。」

    といったエラーが出てしまいます。

    あれこれと手を尽くしたのですが、行き詰まりました。

    どなたか、ご教示いただけましたら幸いです。

    以下、うまく行かないコードの抜粋です。

    ------------------------------------------------------------
                    // メインテーブルの左セル取得
                    objCell = Table_Main.Rows[0].Cells[1];

                    // SQL文の作成
                    dbCmd3 = new System.Data.OleDb.OleDbCommand("SELECT Title FROM Menu'", dbConnection);

                    // SQL文の実行
                    dbDr3 = dbCmd3.ExecuteReader();

                    // リスト表示用の GridView の生成
                    GridView gvMenuList = new GridView();

                    // リストの基になるテーブルの生成
                    DataTable dtMenuList = new DataTable()

                    dtMenuList.Columns.Add(new DataColumn("Title", typeof(HyperLinkField)));

                    while (dbDr3.Read())
                    {
                        String strTitleTmp = dbDr3.GetString(0);

                        HyperLinkField objLink = new HyperLinkField();

                        objLink.Text = strTitleTmp;
                        objLink.NavigateUrl = "http://localhost/test/";
                        objLink.Target = "_blank";

                        DataRow dr = dtMenuList.NewRow();

                        dr["Title"] = objLink;

                        dtMenuList.Rows.Add(dr);
                    }

                    gvMenuList.ID = "gvMenuList";

                    // GridViewのデータソースを指定します。
                    gvMenuList.DataSource = dtMenuList;
                    gvMenuList.DataBind();

                    // セルにGridViewを入れる
                    objCell.Controls.Add(gvAucList);

     

    2006年4月26日 14:00

回答

  •   <Columns>
       <asp:TemplateField HeaderText="スレッド">
        <ItemTemplate>

         <cc1:MultiLineHyperLink ID="HyperLink1" runat="server" NavigateUrl='<%# Eval("スレッドID", "thread.aspx?id={0}") %>'
          Text='<%# Eval("スレッドタイトル") %>'></cc1:MultiLineHyperLink>
        </ItemTemplate>
       </asp:TemplateField>

    オリジナルソースも含んでいるので、例としてはちょっと不適切ではありますが、このようにテンプレート化させて、GridViewにバインドしているID値をリンクに生成させてやるといいでしょう。

    MultiLineHyperLink はただのHyperLinkの継承したものです。

    2006年4月26日 15:10
  • 中さんもかかれてますが。

    DataTableのほうを操作するのではなく、GridViewにHyperLinkFieldを追加してそのTitleやNavigateUrlをデータとバインディングする形にする必要があると思います。
    DataTableがきちんとできてれば後はIDEでちょこちょこ設定変えてあげればそれだけでいけるはず。
    テンプレートにしなくてもいけるんじゃないかな。
    データにTitleやURLの値が含まれてることが前提になりますが。

    2006年4月27日 1:11
  • > 実は、この点で悩んでいたのが、IDE上のデザインビューで表を作成し、特定
    > セル内にGridViewのコントロールをドラッグアンドドロップで追加できなかった
    > のでcsプログラム上で作ることとしておりました。

    手元でやってみましたが、問題なくテーブルの中にGridViewをドラッグ アンド ドロップで追加できました。
    私はメニューのレイアウト-テーブルの挿入でテーブルを追加してそこにGridViewを貼り付けたのですが、これでできませんか?

    #VWDを使い始めたころ、ツールボックスからTableコントロールを貼り付けるとうまく操作できなくて困った記憶がある。。。

     

    2006年4月27日 2:20
  • レイアウトから作った表はただのテーブルタグですね。
    ツールボックスからドラッグ アンド ドロップしたほうはTableコントロールになってます。
    どうもTableコントロールの使い方がよくわかってないので、テーブルタグだけを使ってます。
    表示位置を指定するためだけに使うのであればテーブルタグで十分ですし。

    なお、ツールボックスのHTMLタブの中にあるTableはテーブルタグになるようです。

     

    2006年4月27日 2:43

すべての返信

  •   <Columns>
       <asp:TemplateField HeaderText="スレッド">
        <ItemTemplate>

         <cc1:MultiLineHyperLink ID="HyperLink1" runat="server" NavigateUrl='<%# Eval("スレッドID", "thread.aspx?id={0}") %>'
          Text='<%# Eval("スレッドタイトル") %>'></cc1:MultiLineHyperLink>
        </ItemTemplate>
       </asp:TemplateField>

    オリジナルソースも含んでいるので、例としてはちょっと不適切ではありますが、このようにテンプレート化させて、GridViewにバインドしているID値をリンクに生成させてやるといいでしょう。

    MultiLineHyperLink はただのHyperLinkの継承したものです。

    2006年4月26日 15:10
  • 中さんもかかれてますが。

    DataTableのほうを操作するのではなく、GridViewにHyperLinkFieldを追加してそのTitleやNavigateUrlをデータとバインディングする形にする必要があると思います。
    DataTableがきちんとできてれば後はIDEでちょこちょこ設定変えてあげればそれだけでいけるはず。
    テンプレートにしなくてもいけるんじゃないかな。
    データにTitleやURLの値が含まれてることが前提になりますが。

    2006年4月27日 1:11
  • お返事ありがとうございます。
    GridViewのオブジェクト自体をPage_Load関数内で行おうとしておりましたが、
    ~.aspx内にGridViewを定義しておくのがスマートなのですね。。

    実は、この点で悩んでいたのが、IDE上のデザインビューで表を作成し、特定
    セル内にGridViewのコントロールをドラッグアンドドロップで追加できなかった
    のでcsプログラム上で作ることとしておりました。

    IDE上でセルにGridViewを入れる方法に、一旦Table表外にGridView
    を作成し、列のデザインを施し、ソースビュー上で
    <asp:GridView ID="~> から </asp:GridView>までの行を無理やり
    <asp:TableCell ~> と </asp:TableCell>の間に切り貼りすることででき
    ました。

    テンプレートについても使える時に活用できるよう、少し勉強してみたいと
    思います。

    手探りで勉強中のため、皆様からいただけるキーワードが私には大変
    ありがたいものです。。

    どうもありがとうございました。

    2006年4月27日 2:07
  • > 実は、この点で悩んでいたのが、IDE上のデザインビューで表を作成し、特定
    > セル内にGridViewのコントロールをドラッグアンドドロップで追加できなかった
    > のでcsプログラム上で作ることとしておりました。

    手元でやってみましたが、問題なくテーブルの中にGridViewをドラッグ アンド ドロップで追加できました。
    私はメニューのレイアウト-テーブルの挿入でテーブルを追加してそこにGridViewを貼り付けたのですが、これでできませんか?

    #VWDを使い始めたころ、ツールボックスからTableコントロールを貼り付けるとうまく操作できなくて困った記憶がある。。。

     

    2006年4月27日 2:20
  • どっとねっとふぁん様のご指摘、私がヘマして悩んでいた点にヒットでした。
    DataTableに属性を持ったオブジェクトを入れて、GridViewへ入れようと
    するのがダメなんですね。。(恥)
    DataTableに属性付きオブジェクトを入れ、GridViewのカラムにも同様
    に属性定義をしてBindしても失敗したので、もっと他の問題かと勘違い
    しておりました。

    DataTableでのカラムは単にStringでいいわけなんですね。。
    勉強になりました・・・。

    皆様にも共有できるよう、以下ソースを貼ります。

    --------------------------------------------------------------------
                    objCell = Table_Main.Rows[0].Cells[1];

                    dbCmd3 = new System.Data.OleDb.OleDbCommand("SELECT Title,Url FROM Menu", dbConnection);

                    dbDr3 = dbCmd3.ExecuteReader();

                    GridView gvMenuList = new GridView();
                    DataTable dtMenuList = new DataTable();

                    dtMenuList.Columns.Add(new DataColumn("Title", typeof(String)));
                    dtMenuList.Columns.Add(new DataColumn("Url", typeof(String)));


                    while (dbDr3.Read())
                    {
                        String strTitleTmp = dbDr3.GetString(0);
                        String strUrlTmp = dbDr3.GetString(1);

                        DataRow dr = dtMenuList.NewRow();

                        dr["Title"] = strTitleTmp;
                        dr["Url"] = strUrlTmp;

                        dtMenuList.Rows.Add(dr);
                    }

                    gvMenuList.ID = "gvMenuList";
                    gvMenuList.AutoGenerateColumns = false;


                    HyperLinkField hField = new HyperLinkField();
                    String[] strFields = { "Url" };

                    hField.DataTextField = "Title";
                    hField.DataNavigateUrlFormatString = "Url";
                    hField.DataNavigateUrlFields = strFields;
                    hField.Target = "_blank";

                    gvMenuList.Columns.Add(hField);

                    gvMenuList.DataSource = dtMenuList;
                    gvMenuList.DataBind();

                    objCell.Controls.Add(gvMenuList);

    2006年4月27日 2:22
  • 追加のお返事、感謝です。
    私、IDE左(標準時)のツールボックスから「Table」をドラッグアンドドロップ
    して、その表に対してGridViewを入れようとして失敗していました。

    「レイアウト」メニューから行うと、確かにできますね。(知りませんでした)

    ちなみに、「レイアウト」メニューから作った表と、ツールボックスから作った
    表ではIDE上での見た目も編集の操作感も異なるのですが、この2つの
    表の違いってどのようなものなのでしょうか?

    2006年4月27日 2:28
  • レイアウトから作った表はただのテーブルタグですね。
    ツールボックスからドラッグ アンド ドロップしたほうはTableコントロールになってます。
    どうもTableコントロールの使い方がよくわかってないので、テーブルタグだけを使ってます。
    表示位置を指定するためだけに使うのであればテーブルタグで十分ですし。

    なお、ツールボックスのHTMLタブの中にあるTableはテーブルタグになるようです。

     

    2006年4月27日 2:43
  • そうなんですね、知りませんでした。

    確かに、整形目的でテーブルを使いたかったのですが、何か使いにくいなぁ・・・とは
    思っていました。(笑)

    単純なテーブルタグを知り、これでページが格段に作りやすくなりようです。
    どうもありがとうございました。

    2006年4月27日 3:45
  • 私も何かのデモのビデオ見るまで知りませんでした。
    テーブルタグだと右クリックからセルの連結や行/列の挿入/削除、サイズの変更など自由に操作できてすごい便利ですね。
    このあたり最初に何かで教えてもらわないと気づきにくいですよねぇ。

    #VS2005って高機能になりすぎてなかなか気づかない機能が増えたような気がする。。。

    2006年4月27日 5:24