Search code examples
c#asp.netlistboxpostbackautopostback

ASP.NET populate lists referencing each other on selected index change


I have an ASP.NET control with three listboxes: LBParent, LBChild1 and LBChild2.

LBParent has to be filled programmatically. I do this in Page_Load.

When the user selects a value in LBParent, I want to fill both LBChild1 and LBChild2 with some data, programmatically. The children lists must also keep track of their selected value.

Basically, the parent list is a list of users, the first list is a list of permissions the user has, the second list is a list of permissions the user doesn't have.

My plan is to add two buttons to move permissions between the two lists.

Unfortunately, I cannot get this to work properly.

  • If I populate the parent list in Page_Load, the selected index seems to reset. I used ViewState to save the index... but this seems to require an additional refresh, because it doesn't update after the PostBack. This is not acceptable.

  • If I populate the children listboxes on the OnParentSIC event, there is no way I can keep track of their selected index. The OnChildXSIC events never fire, because the listboxes get repopulated "too soon". (?)

How can I get this to work as intended? Maybe there is a better solution but I'd really like to understand how to get this solution to work, as I can't see a possible solution at the moment.


Control.ascx

<%@ Control Language="C#" AutoEventWireup="true" EnableViewState="True" CodeBehind="..." Inherits="..." %>
<form runat="server">
     <asp:ListBox ID="LBParent" runat="server" CssClass="form-control" 
                  AutoPostBack="true" OnSelectedIndexChanged="OnParentSIC" />                               
     <asp:ListBox ID="LBChild1" runat="server" CssClass="form-control" 
                  AutoPostBack="true" OnSelectedIndexChanged="OnChild1SIC" />                               
     <asp:ListBox ID="LBChild2" runat="server" CssClass="form-control" 
                  AutoPostBack="true" OnSelectedIndexChanged="OnChild2SIC" />
</form>

Control.ascx.cs

protected void Page_Load(object sender, EventArgs e)
{
    // Populate parent
    for(...) LBParent.Items.Add(...);
}

Solution

  • The Onchange-event fires, but before that the OnLoad fires. So:

    1. The user clicks on an selection
    2. A postback is triggered
    3. At the server the Onload fires (and rebuilds the list)
    4. The OnSelectedIndexChanged fires (which lost the selection by now)

    So I would try to save the current-selected-index before you rebuild the list (in the Onload).

    If you restore it later on while you are in the same 'postback' you can save it in a simple variable. No need to store in a Viewstate or Session.