Search code examples
c#.netasp.netdata-binding2-way-object-databinding

Two way databinding in ASP.NET


Let say that we have an object

class Entity
{
    public string ID {get; set;}
    public string Name {get; set;}
}

I want to bind properties to two textboxes on a page something like this:

<asp:FormView ID="FormView" runat="server">
  <ItemTemplate>
    <asp:textbox ID="TextId" Text='<%# Bind("ID") %>'/>
    <asp:textbox ID="TextId" Text='<%# Bind("Name") %>'/>
  </ItemTemplate>
</asp:FormView>

and then write this in code behind

public EntityObject
{
    get { return ViewState["Entity"] as Entity; }
    set { ViewState["Entity"] = value; }
}

protected override void OnInit(EventArgs e)
{
    if (EntityObject== null)
        EntityObject= new EntityObject();

    FormView.DataSource = new[] { EntityObject };
    FormView.DataBind();
    base.OnInit(e);
}

And when I enter values in textboxes I expect EntityObject to have these values in properties when page reloads after PostBack, but properties are always null.


Solution

  • Sadly to say that, but ASP.NET does not support two-way binding to .net objects... instead you can use something like "manual binding" on every post back (here AddIncomeSources is RepeaterControl)

    public List<Income> AdditionalIncomeList 
    {
        get { return ViewState["AdditionalIncome"] as List<Income>; }
        set { ViewState["AdditionalIncome"] = value; }
    } 
    
    foreach (RepeaterItem item in AddIncomeSources.Items)
    {
        var amount = (TextBox)item.Controls.Cast<Control>().First(c => c.ID == "Amount");
        var document = (DropDownList)item.Controls.Cast<Control>().First(c => c.ID == "Document");
        AdditionalIncomeList[item.ItemIndex].Amount = amount.Text.ToDouble();
        AdditionalIncomeList[item.ItemIndex].IncomeDocument = document.SelectedValue;
    }
    
    AddIncomeSources.DataSource = AdditionalIncomeList;
    AddIncomeSources.DataBind();