Architect's Log

I'm a Cloud Architect. I'm highly motivated to reduce toils with driving DevOps.

Repeaterコントロール内に配置したコントロールのイベントをハンドリングする

Repeaterコントロール内に配置したコントロールのイベントをハンドリングする際の注意点です。
ここでは例としてRepeaterコントロール内部にButtonを配置しています。

ソースコード

aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <div>
            <asp:Repeater ID="Repeater1" runat="server" EnableViewState="true">
                <ItemTemplate>
                    <div>
                        <%# ((WebApplication1.Item) Container.DataItem).ID %>
                        <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
                    <div>
                </ItemTemplate>
            </asp:Repeater>
        </div>
        <div>
            <asp:Label ID="Label1" runat="server" Text="" />
        </div>
    </div>
    </form>
</body>
</html>
aspx.cs
using System;
using System.Collections.Generic;

namespace WebApplication1 {
    public partial class _Default : System.Web.UI.Page {
        protected void Page_Load(object sender, EventArgs e) {
            if (IsPostBack == false) {
                Repeater1.DataSource = new List<Item>() {
                    new Item() { ID = "1" },
                    new Item() { ID = "2" }
                };
                Repeater1.DataBind();
            }
        }

        protected void Button1_Click(object sender, EventArgs e) {
            Label1.Text = "ボタンがクリックされました。";
        }
    }

    public class Item {
        public string ID { get; set; }
    }
}

動作

初期表示

ボタンクリック

注意点

ポストバックのときはDataBindしない

Repeaterを使用する場合に限りませんが、ポストバックのときもPage.Loadは発生します。
イベントの発生順序はPage.Load→Button.Clickの順なので、ポストバックのときにもDataBindしてしまうとButton.Clickが発生しません。

RepeaterのEnableViewStateをtrueにする

EnableViewStateをfalseにするとポストバックの際に送信されるViewStateにRepeater内部のコントロールが含まれないので、Button.Clickが発生しません。