martin36
martin36

Reputation: 2363

ASP.NET Loading dynamic controls based on value in ViewState

I have been looking all over for a solution to this, but I haven't found it.

Here is the problem, I have a static created table that contain a list over other lists:

<table class="styled-list">
    <tbody>
        <tr>
            <td><a>Lista 1</a></td>
            <td>
                <asp:Button runat="server" ID="btnDelete1" />
                <asp:Button runat="server" ID="btnEdit1" />
            </td>
        </tr>
        <tr>
            <td><a>Lista 2</a></td>
            <td>
                <asp:Button runat="server" ID="btnDelete2" />
                <asp:Button runat="server" ID="btnEdit2" />
            </td>
        </tr>
    </tbody>
</table>

When the edit button for any of these lists are clicked another list should be shown. To know which of the lists has been selected I save the name of the list in ViewState.

private string ListNameOfSelected
{
    get
    {
        if (ViewState["ListNameOfSelected"] != null) return (string)ViewState["ListNameOfSelected"];
        else return "";
    }
    set { ViewState["ListNameOfSelected"] = value; }
}


protected void btnEdit_Click(object sender, EventArgs e, string name)
{
    ListNameOfSelected = name;
    RenderPersonsInList();
}

The RenderPersonsInList() function will create a list with the persons in the selected list.

private void RenderPersonsInList()
{
    txtNameInTitle.InnerText = ListNameOfSelected;
    TableRow tr;
    TableCell nameCell, emailCell, deleteCell;
    ImageButton deleteButton;
    Guid[] ids = new Guid[] { };
    string[] names = new string[] { };
    string[] emails = new string[] { };

    switch (ListNameOfSelected)
    {
        case "Lista 1":
            ids = new Guid[] { Guid.NewGuid(), Guid.NewGuid() };
            names = new string[] { "Anonymous1", "Anonymous2" };
            emails = new string[] { "[email protected]", "[email protected]" };
            break;
        case "Lista 2":
            ids = new Guid[] { Guid.NewGuid() };
            names = new string[] { "Anonymous3" };
            emails = new string[] { "[email protected]" };
            break;
        default:
            break;
    }


    for (int i = 0; i < names.Length; i++)
    {
        Guid personID = ids[i];
        tr = new TableRow
        {
            ID = "row-" + personID.ToString()
        };
        nameCell = new TableCell
        {
            Text = names[i]
        };
        emailCell = new TableCell
        {
            Text = emails[i]
        };
        deleteCell = new TableCell();
        deleteButton = new Button
        {
            ID = personID.ToString()
        };
        deleteButton.Click += (sender, EventArgs) => { DeleteButton_Click(sender, EventArgs, names[i], personID); };
        deleteCell.Controls.Add(deleteButton);
        tr.Controls.Add(nameCell);
        tr.Controls.Add(emailCell);
        tr.Controls.Add(deleteCell);
        tbListMembers.Controls.Add(tr);
    }
    pnlViewList.Visible = true;

}

Now the problem is that when the user clicks the deleteButton in the dynamically created list, there is a PostBack and the list needs to be recreated. But in order for the click listeners to work the list must be created in the Page_Init or Page_PreInit functions, and here the ViewState has not yet been initiated.

Is there anyway to know which list the user has selected when creating the the dynamic list, either using ViewState or another way?

Thanks

Upvotes: 1

Views: 341

Answers (1)

Brian Cryer
Brian Cryer

Reputation: 2226

You are almost there. The solution is not to use ViewState. This is because (as you have identified) ViewState values aren't available in PageInit, yet you need the value which is the problem you are hitting.

Instead use a hidden value - HiddenField control will do. Of course during PageInit controls won't have had their values loaded either. So to get the value use Page.Request.Params[MyHiddenField.UniqueID]

Upvotes: 1

Related Questions