新米エンジニアの失敗再発防止メモ

自分そしてこの世界の皆が、同じ失敗をしないためのメモ

Twitterやってます!@rakuton_t
欲しいものリストのブタメンを送ってくれた方、ありがとうございます!

Repeaterコントロールの中で分岐処理(データーソースのデータを用いる)

やりたいこと

<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>

// ここでデータソースのデータを用いて分岐処理する

</ItemTemplate>
</asp:Repeater>    

上記のように、Repeaterコントロールの中で、
データバインディング式を用いて分岐し、表示内容を制御したいとする。

問題点

普通にできそうだが、普通にできない。

<%# if( Eval(..) == "hoge" ) {%>
<%} %>

これだとエラーとなる。
「<%#」 (データバインディング式)を使う場合、そのブロック内で値を返さなければならない。
かといってデータバインディング式を使わなければデータソースを用いることはできない。

解決案

私が思いつく限りではこんなところだ。

・1ブロック内で分岐し、値を返す

・データソースを引数に指定し、メソッドの中で分岐処理

・ユーザーコントロールを利用する。

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>    

私の思いつく限りでは、この方法が一番自由度が高く、シンプル。
ただし、ユーザーコントロールを定義しなくてはいけない時点で面倒ではあるが...

私の記事が役に立ったら、どうぞ何か買ってください!→ Amazon欲しいものリスト