views:

307

answers:

2

I have an ASP Page that uses two listboxes and a third party control (Fluent.ListTransfer) to transfer values from one list to the other. Fairly standard stuff:

<td>
    <asp:ListBox ID="ListBoxAvailable" Runat="server"  
        SelectionMode="Multiple" EnableViewState="true">
    </asp:ListBox>
</td>
<td style="vertical-align: middle">
    <a href="#" onclick="<%= ListTransfer1.ClientMoveSelected %>" ><img src="img/RightArrow.jpg" alt=">>"/></a>
    <br />
    <a href="#" onclick="<%= ListTransfer1.ClientMoveBackSelected %>"><img src="img/LeftArrow.jpg" alt="<<"/></a>

</td>
<td>
    <asp:ListBox ID="ListBoxSelected" Runat="server"  
        SelectionMode="Multiple" EnableViewState="true">
    </asp:ListBox>
</td>

On the Controls Page_load event, I set the content of the 'available' and 'selected' box with some sql:

    protected void Page_Load(object sender, EventArgs e)
    {

        if (IsPostBack)
            return;

        // Some code to work through a recordset, adding values 
        // to the selected or available list boxes

I assumed that on postbacks, the viewstate would take care of the state of listboxes, as changed by the user (after all, they are standard ASP controls). However, both list boxes are blank if I do a postback.

What's the proper way to maintain the state of the listboxes between postbacks?

Thanks for any help

Ryan

A: 

If I understand your code correctly you are moving ListItems on the client side from one ListBox to another. But ListBoxes do not submit their whole content - only selected items. So you have to maintain that. I don't know, if Fluent.ListTransfer will do that for you.

Arthur
+1  A: 

ViewState is like a "spy" on the client side. Whenever there's a change in the client side, the ViewState will report back (read: PostBack) the changes to the server so that the server can re-process the page.

Unfortunately, if we alter contents of a control like ListBox using client-side scripts, ViewState does not see it.

I guess your Fluent.ListTransfer is a client side function.

Some solutions:

The listbox store in ViewState only the selected item (I guess only the index), not all the items from list, so it knows only to restore the selected item, not the whole list. Is a little bit strange but is logic. To mantain in ViewState all the items you can write a new ListBox derived from ListBox or HtmlSelect, but you must handle in the same time the possibility that the items from list box be modified on client using javascript code.


When a page posts back none of the items in a listbox are sent back to the server EXCEPT those that are SELECTED on the client. This makes sense when you think about it. Forget about viewstate and all the rest. You can select multiple items so make all the items you add to listbox 2 selected.


Another workaround to this, but not so elegant. The basic idea is to record all the items on ONE LISTBOX to a control, and repopulate the listboxes using the control's value everytime the page being posted back. Hopefully somebody could come up with something better:

  1. Put a HIDDEN input in your web page. Remember to put RUNAT=SERVER attribute so that you can reference your input from your ASP.NET code behind.

  2. In your Javascript, whenever you change the contents of one listbox, concatenate all the values - using a separator - and put the value into your HIDDEN input.

  3. On your Page_Load code, put the code to read the HIDDEN input, separate the values, and fill in the listboxes.

Hope this all helps...

Manish
Very helpful. Thank you!
Ryan