How do I bind a repeater to a List<Person> to also update the bound items? (2-way)

18,690

Solution 1

The simple answer is that the Repeater control does not support the kind of two-way databinding that you are looking for. On top of that, the DataItem property is only used during the creation of the repeater item, and after the ItemDataBound event, it is set to nothing. So you cannot use that property to get the original object you used when creating the specific repeater item after postback (as you are doing in your pseudocode).

You will have to loop through the repeater items, as you suggested (make sure to check that the item is of ListItemType.Item or AlternatingItem before doing anything) and then extract the values from the textboxes and use them in an update.

Solution 2

If you Bind the Repeater with the person list you want like

this.Repeater1.DataSource =  GetPersons();

while GetPersons() is a method returning a list of person objects you could use

<asp:TextBox ID="txtForename" runat="server" Text='<%# Eval("Forename") %>' />

Solution 3

In addition to the above, you also need to bind the repeater to the List. Right now the text boxes are assigned to the value of the Forename (or potentailly bound if you use the

<# Bind("Forename") %>

tag), but the Repeater Container has no DataItem.

Share:
18,690
ilivewithian
Author by

ilivewithian

On a good day, I'm a high functioning idiot. I'm hoping for more good days.

Updated on June 21, 2022

Comments

  • ilivewithian
    ilivewithian almost 2 years

    If I have a List < Person > where person is defined by the class

    class Person
    {
       string Forename
       {
          get;set;
       }
       string Surname
       {
          get; set;
       }
    }
    

    And I bind it to an asp repeater control that looks like this:

    <asp:Repeater ID="Repeater1" runat="server">
        <ItemTemplate>
            <asp:Label ID="lblForename" runat="server" Text="Forname" AssociatedControlID="txtForename" />
            <asp:TextBox ID="txtForename" runat="server" Text='<%# ((Person)Container.DataItem).Forename %>' />
            <br />
            <asp:Label ID="lblSurname" runat="server" Text="Forname" AssociatedControlID="txtSurname" />
            <asp:TextBox ID="txtSurname" runat="server" Text='<%# ((Person)Container.DataItem).Surname %>' />
            <br />
        </ItemTemplate>
    </asp:Repeater>
    

    What is the best way to get the data that the user types in back into the objects?

    I thought that the whole point of data binding was that this was effectively handled for you, but when I inspect the Repeater1.Items collection, there are no changes made. Do I have to write code to do something along the lines of

    //This is only intended to be pseudo code
    for each item in Repeater1.Items
        ((Person)item.DataItem).Forename = item.FindControl("txtForname").Text;
    end for
    

    If that is the case, why is the DataItem property always empty?

    Additional info:

    I am already calling code the the effect of

    this.Repeater1.DataSource =  this.PersonList;
    this.Repeater1.DataBind();
    

    I've tried using Bind("Forename"), but this doesn't seem to bring the info from the TextBox back into the object, do I have to do this manually?