Ryan
Ryan

Reputation: 253

Why is my ASP.NET Repeater data not available in load events via code behind?

I have an ASP.NET repeater that is being populated via a datasource. The data loads and presents perfectly on the screen, but all attempts to access any row of data in that repeater via code behind during the load phase are unsuccessful. I can access everything perfectly on a form submit, once the repeater has rendered on the screen, but in every load-related event I have tried (Load, Init, PreRender, DataBind, etc), it shows as empty. Is it necessary to populate the repeater programatically in code behind, rather than ASPX markup, in order to access this data during the load phase or am I just doing something wrong?

ASPX snippet:

<div runat="server" id="rpt3" style="display: block;">
<p class="approvalHeaderText">
Rejected Items</p>
<asp:Repeater ID="RptRejected" runat="server" DataSourceID="SQL_EmployeeGetRejectedEdits">
<ItemTemplate>
<tr class="gridToggleWhite gridVisible" id="<%# Eval("RecID") %>_cont">
<td>
<%# Eval("OrderID")%>
</td>

Code behind snippet - tried in several events (assume all variables have been declared):

For i = 0 To RptRejected.Items.Count - 1
'Obtain current week's Expenses
curExpVal = RptRejected.Items(i).FindControl("ExpensePay")
If Not IsNothing(curExpVal) Then
If curExpVal.Text = "" Then
insertExp = 0
Else
insertExp = CSng(curExpVal.Text)
End If
Else
insertExp = 0
End If
Next

Upvotes: 0

Views: 1702

Answers (3)

Ryan
Ryan

Reputation: 253

My key mistake was using Eval() instead of the DataBinder.Eval() method. While the result is the same on the screen, Eval() does not trip the OnItemDataBound event. Once I switched my markup over to DataBinder.Eval(), everything fell into place. Thanks, everyone, for your ideas.

Upvotes: 0

Ray Cheng
Ray Cheng

Reputation: 12566

R1_Load and R1_ItemDataBound should be used to populate your data and R1_ItemCommand should be used to handle the button actions.

aspx

<asp:Repeater runat="server" ID="R1" OnItemCommand="R1_ItemCommand" OnItemDataBound="R1_ItemDataBound"
    OnLoad="R1_Load">
    <HeaderTemplate>
        <table>
    </HeaderTemplate>
    <ItemTemplate>
        <tr>
            <td>
                <asp:TextBox runat="server" ID="txt"></asp:TextBox><asp:Button runat="server" ID="btn"
                    Text="Add" CommandName="AddOne" />
            </td>
        </tr>
    </ItemTemplate>
    <FooterTemplate>
        </table> </FooterTemplate>
</asp:Repeater>

aspx.cs

protected void R1_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        var items = new List<int>();
        for (int i = 0; i < 5; i++)
        {
            items.Add(i);
        }
        R1.DataSource = items;
        R1.DataBind();
    }
}

protected void R1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
    {
        var txt = e.Item.FindControl("txt") as TextBox;
        txt.Text = Convert.ToString(e.Item.DataItem);
    }
}

protected void R1_ItemCommand(object source, RepeaterCommandEventArgs e)
{
    if (e.CommandName == "AddOne")
    {
        var txt = e.Item.FindControl("txt") as TextBox;
        txt.Text = (Convert.ToInt32(txt.Text) + 1).ToString();
    }
}

Upvotes: 0

Magnus
Magnus

Reputation: 46919

You can use the ItemDataBound event (and you don't need the loop):

Sub rpt3_ItemDataBound(Sender As Object, e As RepeaterItemEventArgs)
  If (e.Item.ItemType = ListItemType.Item) OrElse _
            (e.Item.ItemType = ListItemType.AlternatingItem) Then

    Dim curExpVal = e.Item.FindControl("ExpensePay")
    If Not IsNothing(curExpVal) Then
      If curExpVal.Text = "" Then
        insertExp = 0
      Else
        insertExp = CSng(curExpVal.Text)
      End If
    Else
      insertExp = 0
    End If
  End If

End Sub

Upvotes: 1

Related Questions