Search code examples
c#asp.netooplifecycle

Dynamic form and viewstate


I have a problem that I try to solve in the last few says, with no success.

I have several classes, each one has several fields types. They all inherit one class, like that:

class Item
{
    public TextField Name { get; set;}
}

class ItemA : Item
{
    public DropDownListField Area { get; set;}
}

class ItemB : Item
{
    public CheckBoxListField Season { get; set;}
}

I created a form that should generate the fields depending to the request.

It's structured so: I created an empty table, and foreach class property I add TableRow with the appropriate control to the table . I need to add the entire TableRow and not just the control, because each control required unique adjustment.

The problem is: The Controls looses thier value on post back, and I can't send the value to the database. The strange thing is that the DropDownLists and CheckBoxLists not looses their value, but all others (TextBoxes, single CheckBox, etc.) yes.

It's very complicated to save each value in viewstate or session, because I get the unique TableRow from the class, and I can't save the value to viewstate in the class.

What can I do? What is the correct way to make it works?

I know that this issue already asked, but I didn't find an answer that helped me to solve my problem.

Thank You.

I add the aspx page and code behind:

aspx page:

<%@ Page Title="" Language="C#" MasterPageFile="~/Admin/AdminMaster.master" ValidateRequest="false" AutoEventWireup="true" CodeFile="Add.aspx.cs" Inherits="Admin_Add" MaintainScrollPositionOnPostback="true" %>

<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
    <link href="<%=Page.ResolveClientUrl("~/Admin/css/Add.css")%>" rel="stylesheet" />

    <script src="<%=Page.ResolveClientUrl("~/Admin/Scripts/ckeditor/ckeditor.js")%>"></script>
    <script src="<%=Page.ResolveClientUrl("~/Admin/Scripts/ckeditor/config.js")%>"></script>

</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
    <div id="Add">
        <h1><asp:Label ID="PageTitle" runat="server" /></h1>
        <asp:Panel ID="p1" runat="server" />
        <asp:Table runat="server" ID="addTable">
        </asp:Table>
        <asp:Button runat="server" ID="send" Text="Save" OnClick="send_Click" />
        <asp:Button runat="server" Text="btn" />
    </div>
</asp:Content>

code behind:

protected void Page_Init(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            string c = "Track";
            Session["Item"] = Item.GetItem(c);
        }

        Item item = (Item)Session["Item"];

        List<PropertyInfo> list = new List<PropertyInfo>();

        list.AddRange(item.GetType().GetProperties());

        foreach (var p in list)
        {
            if (p.PropertyType.IsSubclassOf(typeof(Field)))
            {
                var t = (Field)p.GetValue(item, null);
                addTable.Rows.Add(t.CreateEditingRow());
            }
        }
    }

Solution

  • I don't know why, but the problem was that I set the controls ID. When I don't set the ID, all is working properly, also in Page_Load event.

    Thank you very much.