- PR -

Repeaterコントロールで条件分岐

1
投稿者投稿内容
常連さん
会議室デビュー日: 2004/10/27
投稿数: 21
投稿日時: 2004-10-27 16:56
初めて投稿させていただきます。

Repeaterコントロールを使いテーブルを出力際に、行に表示するデータによってはRowspanの値を
設定して行を結合させる場合の方法はどのようなコードになるのでしょうか?
自分で調べてサンプルを作ってみたのですが、出来上がったものを見るとRepeaterコントロールの使い方を
間違っているように感じてしまいます。
以下にサンプルをのせさせて頂きます。

DB
・Ordersテーブル
--------------------------
| OrderId | CustomerId |
--------------------------
| 10248  |  aaaa     |
--------------------------
| 10249  |  bbbb     |
--------------------------

・Order Details テーブル
-----------------------------------
| OrderId | UnitPrice | Quantity |
-----------------------------------
| 10248  |   5     |   3     |
-----------------------------------
| 10248  |   10    |   4     |
-----------------------------------
| 10248  |   15    |   5     |
-----------------------------------
| 10249  |   20    |   6     |
-----------------------------------
| 10249  |   25    |   7     |
-----------------------------------

以上の2つのテーブルを"ORDERS"データテーブルと"ORDER DETAILS"データテーブルにFillし、DataSetに追加後、Relationsに
"R_ORDER_ID"リレーションを追加しました。
RepeaterコントロールのDataSourceには"ORDER"データテーブルを設定しています。

RepeaterコントロールのItemDataBoundイベントに以下のように記述します。
private void Repeater1_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
{
    DataRowView drv = null;
    DataRow[] rChilds = null;

    if(e.Item.ItemType != ListItemType.Item)
    {
      return;
    }

    drv = (DataRowView)e.Item.DataItem;
    rChilds = drv.Row.GetChildRows("R_ORDER_ID");

    e.Item.Controls.Add(new LiteralControl("<tr>"));
    e.Item.Controls.Add(new LiteralControl(string.Format("<td rowspan=\"{0}\">{1}</td>", rChilds.Length, ((DataRowView)e.Item.DataItem)["OrderId"])));
    e.Item.Controls.Add(new LiteralControl(string.Format("<td rowspan=\"{0}\">{1}</td>", rChilds.Length, ((DataRowView)e.Item.DataItem)["CustomerId"])));
    e.Item.Controls.Add(new LiteralControl(string.Format("<td>{0}</td>", rChilds[0]["UnitPrice"])));
    e.Item.Controls.Add(new LiteralControl(string.Format("<td>{0}</td>", rChilds[0]["Quantity"])));
    e.Item.Controls.Add(new LiteralControl("</tr>"));

    for(int i = 1; i < rChilds.Length; i++)
    {
      e.Item.Controls.Add(new LiteralControl("<tr>"));
      e.Item.Controls.Add(new LiteralControl(string.Format("<td>{0}</td>", rChilds[i]["UnitPrice"])));
      e.Item.Controls.Add(new LiteralControl(string.Format("<td>{0}</td>", rChilds[i]["Quantity"])));
      e.Item.Controls.Add(new LiteralControl("</tr>"));
    }
}

結果として出力されるテーブル
--------------------------------------------------
| Order Id | CustomerId | UnitPrice | Quantity |
--------------------------------------------------
|        |           |   5     |   3     |
| 10248   |  aaaa     |   10     |   4     |
|        |           |   15     |   5     |
--------------------------------------------------
| 10249   |  bbbb    |   20     |   6      |
|         |           |   25     |   7     |
--------------------------------------------------

自分で書いたコードで期待していた結果は取れたのですが、Repeaterコントロールを使って出力する行ごとに出力する値を
変更する場合、他にスマートに行う方法があるのでしょうか?

<Repeater />タグ内の<ItemTemplate />タグ内で記述できる方法などがありましたら情報を頂けないでしょうか?

長文でご迷惑かと思いますが、よろしくお願いします。

開発環境
Visual Studio .NET 2003
IIS 5.0
MSDE 2000
Windows 2000 Professional
Ten.
ベテラン
会議室デビュー日: 2003/04/03
投稿数: 67
投稿日時: 2004-10-28 11:20
Rowspanで行を結合させる方法ではありませんが、このような場合DataGridやRepeaterを入れ子にすると、簡単に同様な結果を得ることができます。

以下のようにDataGridの中にRepeaterを置いたものを定義し、DataGridにOrdersテーブルをバインドするだけでOKです。
コード:
<asp:DataGrid id=DataGrid1 runat="server" AutoGenerateColumns="False">
<Columns>
<asp:BoundColumn DataField="OrderId" ReadOnly="True" HeaderText="Order Id"></asp:BoundColumn>
<asp:BoundColumn DataField="CustomerId" ReadOnly="True" HeaderText="CustomerId"></asp:BoundColumn>

<asp:TemplateColumn HeaderText="UnitPrice">
<ItemTemplate>
<asp:Repeater id="R1" runat="server" DataSource='<%# Container.DataItem.Row.GetChildRows("R_ORDER_ID") %>'>
<ItemTemplate><%# Container.DataItem("UnitPrice").ToString() %><br></ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:TemplateColumn>

<asp:TemplateColumn HeaderText="Quantity">
<ItemTemplate>
<asp:Repeater id="R2" runat="server" DataSource='<%# Container.DataItem.Row.GetChildRows("R_ORDER_ID") %>'>
<ItemTemplate><%# Container.DataItem("Quantity").ToString() %><br></ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:TemplateColumn>

</Columns>
</asp:DataGrid>

常連さん
会議室デビュー日: 2004/10/27
投稿数: 21
投稿日時: 2004-10-28 13:10
ご意見ありがとうございます。
BBSへの投稿は久しぶりだったのでレスがついた時はとても嬉しかったです。

Tenさんに教えていただいたコードを早速自分の環境下で試してみたのですが実行結果を見てから自分の書いた質問の間違いに気がつきました。
私の欲しい結果なのですが、最初に書いた結果ではなく以下のような形の表でした。
--------------------------------------------------
| Order Id | CustomerId | UnitPrice | Quantity |
--------------------------------------------------
|        |           |   5     |   3     |
|        |           |-----------------------
| 10248   |  aaaa     |   10     |   4     |
|        |           |-----------------------
|        |           |   15     |   5     |
--------------------------------------------------
| 10249   |  bbbb     |   20     |   6    |
|         |           |-----------------------
|         |            |   25     |   7     |
--------------------------------------------------

このような形に表を出力するにはOrderId=10248の1行目を出力する際のOrderIdとCustomerIdの<td>タグのRowspanの値を3に設定して、同じく4行目のOrderId=10249の1行目を出力するときのOrderIdとCustomerIdの<td>タグのRowspanの値を2に設定してあげないといけないと思っています。
条件によって出力されるタグの値を変更するような場合はどのように行えばよいのでしょうか?

以上、よろしくお願いします。
1

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