Tuesday, October 03, 2006

About SqlDataSource control

I've been running a problem of losing the selected items in a listbox, which is bound to the SqlDataSource control on every postback. The code is :


<asp:ListBox ID="lstBox" runat="server" CssClass="listbox-flat" DataSourceID="objSQL" DataTextField="userFullName" DataValueField="RID" SelectionMode="Multiple" Width="335px" Enabled="False"></asp:ListBox>

<asp:SqlDataSource ID="objSQL" runat="server" ConnectionString="<%$ ConnectionStrings:dbConnectionString %>" SelectCommand="SELECT * FROM Table1"> </asp:SqlDataSource>


As far as I remember, the selections of ListBox SHOULD be retained on the postback since the ViewState of the control will be saved in the SaveViewState event after the binding, but the thing goes weird unexpectedly :(. Since the automatic databinding performed by the SqlDataSource takes place in the Page_PreRender event (You can check it by using Page Tracing). Here is the screenshot:


* The ListBox is bound to the DataSource control.

Eventually, I used another way round by programmatically binding the ListBox in that PreRender event with IsPostBack checking. (No choice, this is the best way I could think of, I will find out the cause of the problem later)

Steps
1. Set the DataSourceID property of ListBox to empty (So that it would not be bound to the SqlDataSource until runtime)

2. Obtain the SqlDataSource's IEnumerable collection by calling the DataSource's Select() method with no argument.

3. Call the ListBox's DataBind() method


Code

protected void Page_PreRender(Object sender, EventArgs e)
{
if(!IsPostBack)
{
   lstBox.DataSourceID = String.Empty;
   lstBox.DataSource = objSQL.Select(DataSourceSelectArgument.Empty);
   lstBox.DataBind();
}
}


Good Practice
For ordinary data binding operations like binding DataGrid, ListBox, DropDownList, etc, we normally perform in Page_Load() event. Actually, we can do the binding in the Page_PreRender event (bind the data-bound controls as late as possible) before the controls are about to be rendered.

Do always check IsPostBack before performing any data binding to reduce the roundtirp to server.


Digging into detailed observations...

No comments: