やりたいこと
<asp:Repeater ID="Repeater1" runat="server"> <ItemTemplate> // ここでデータソースのデータを用いて分岐処理する </ItemTemplate> </asp:Repeater>
問題点
普通にできそうだが、普通にできない。
<%# if( Eval(..) == "hoge" ) {%> <%} %>
これだとエラーとなる。
「<%#」 (データバインディング式)を使う場合、そのブロック内で値を返さなければならない。
かといってデータバインディング式を使わなければデータソースを用いることはできない。
1ブロック内で分岐し値を返す
<%# Eval("hoge") == "hoge" ? "aaa" : "bbb" %>
1行で済むような分岐ならば、三項演算子でこれで済む。
だがもっと複雑な処理をしたい場合は不便だ。
データソースを引数に指定し、メソッドの中で分岐処理
<%# BunkiMethod(Eval("hoge")) %>
public string BunkiMethod(string hoge){ if( Eval("hoge") == "a"){ return "A"; } else { retrun "B"; } }
この方法も簡単で複雑な処理もできるが、
フロント側(aspx側)で表示内容を変更できないのが難点だ。
ユーザーコントロールを使用する
まずはユーザコントロールを定義する。
WebUserControl.ascx.cs
public partial class WebUserControl : System.Web.UI.UserControl { protected void Page_Load(object sender, EventArgs e) { } /// <summary>データソース受取用</summary> public DataRowView data { get; set; } /// <summary>データソースよりデータを取り出す</summary> public string hoge { get { return (string)data["hoge"]; } } }
※これはデータソースがDataRowView型の場合である。型に応じて変えること。
WebUserControl.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="WebUserControl.ascx.cs" Inherits="WebUserControl" %> <!-- 以下ではデータバインディング式を使わないので複数ブロックに及ぶif文が使える --> <% if(this.hoge == "hoge") {%> <asp:Label runat="server">ほげほげ</asp:Label> <asp:LinkButton runat="server">ホげボタン</asp:LinkButton> <%} else {%> <asp:Label runat="server">はげはげ</asp:Label> <%} %>
ユーザーコントロール呼び出し
<asp:Repeater ID="Repeater1" runat="server"> <ItemTemplate> <uc:WebUserControl data="<%# Container.DataItem %>" runat="server" /> </ItemTemplate> </asp:Repeater>
私の思いつく限りでは、この方法が一番自由度が高く、シンプル。
ただし、ユーザーコントロールを定義しなくてはいけない時点で面倒ではあるが...