profile for Cullen Tsering at Stack Overflow, Q&A for professional and enthusiast programmers

Wednesday, April 15, 2009

Move selection to the next item in ListBox when the record is deleted in a FormView

In my previous post, I showed the method to highlight a newly inserted record from the FormView in the ListBox. Conversly, when a record is deleted from the FormView, I'd like to move to the next item in the ListBox if there is one. If the deleted item is last item, then move to the previous one.

Below is the definition of the ListBox:
<asp:ListBox ID="listBoxEmployees" runat="server"
AutoPostBack="true"
DataSourceID="odsListBoxEmployees"
DataTextField="EmployeeName"
DataValueField="EmployeeID"
onselectedindexchanged="listBoxEmployees_SelectedIndexChanged"
ondatabound="listBoxEmployees_DataBound">
</asp:ListBox>

Below is the definition of the FormView:
<asp:FormView
ID="fvEmployee"
runat="server"
DataKeyNames="EmployeeID"
DataSourceID="odsEmployee"
oniteminserted="fvEmployee_ItemInserted"
>

Below is the definition of the Object Data Source:

<asp:ObjectDataSource
ID="odsEmployee"
runat="server"
TypeName="Employees"
SelectMethod="SelectOne"
InsertMethod = "Insert"
UpdateMethod = "Update"
DeleteMethod = "Delete"
ConflictDetection="OverwriteChanges"
oninserted="odsEmployee_Inserted"
ondeleting="odsEmployee_Deleting"
>
<SelectParameters>
<asp:ControlParameter Name="EmployeeID" Type="Int32" Direction="Input" ControlID="listBoxEmployees" PropertyName="SelectedValue" />
</SelectParameters>
<InsertParameters>
<asp:Parameter Name="EmployeeName" Size="80" Direction = "Input" Type="String" />
</InsertParameters>
<UpdateParameters>
<asp:Parameter Name="EmployeeID" Type="Int32" Direction="Input" />
<asp:Parameter Name="EmployeeName" Size="80" Direction = "Input" Type="String" />
</UpdateParameters>
</asp:ObjectDataSource>

Handle Deleted event of the ODS so before the record is deleted in the FormView, we'll store the next item in the ListBox in view state as follows:

protected void odsEmployee_Deleting(object sender, ObjectDataSourceMethodEventArgs e)
{
//if there are more one items in the list
if (listBoxEmployees.Items.Count > 1)
//if the record to be deleted is not the last one in the list
if (listBoxEmployees.SelectedIndex < listBoxEmployees.Items.Count-1)
{
//store the next item's value
ViewState["EmployeeID"] = listBoxEmployees.Items[++listBoxEmployees.SelectedIndex].Value;
}
else
//if it is the last one, then store the previous item's value
ViewState["EmployeeID"] = listBoxEmployees.Items[--listBoxEmployees.SelectedIndex].Value;
}

The code above is self explanatory.

Next handle the DataBound event of the ListBox control as follows:

protected void listBoxEmployees_DataBound(object sender, EventArgs e)
{
if (listBoxEmployees.Items.Count > 0)
if (ViewState["EmployeeID"] != null)
{
listBoxEmployees.SelectedValue = ViewState["EmployeeID"].ToString();
}
else listBoxEmployees.SelectedIndex = 0;
ViewState.Remove("EmployeeID");
}

This will set the SelectedValue of the ListBox to the value in the view state. After we used the value in the view state, we remove it.

Highlight ObjectDataSource bound ListBox after ObjectDataSource bound FormView inserted a brand new record

I have a ListBox (I'll call it listBoxEmployees) that is bound to an ObjectDataSource (I'll call odsListBoxEmployees).

<asp:ListBox ID="listBoxEmployees" runat="server"
AutoPostBack="true"
DataSourceID="odsListBoxEmployees"
DataTextField="EmployeeName"
DataValueField="EmployeeID"
onselectedindexchanged="listBoxEmployees_SelectedIndexChanged"
ondatabound="listBoxEmployees_DataBound">
</asp:ListBox>

It displays Employee Name as Text and stores EmployeeID as Value in the list.

Then I have a FormView which is bound to another ObjectDataSource (I'll call it odsEmployee) which retrieves an individual record when an item is selected in the ListBox control. Below is the FormView definition:
<asp:FormView
ID="fvEmployee"
runat="server"
DataKeyNames="EmployeeID"
DataSourceID="odsEmployee"
>

Below is the ODS definition:
<asp:ObjectDataSource
ID="odsEmployee"
runat="server"
TypeName="Employees"
SelectMethod="SelectOne"
InsertMethod = "Insert"
UpdateMethod = "Update"
DeleteMethod = "Delete"
ConflictDetection="OverwriteChanges"
oninserted="odsEmployee_Inserted"
ondeleting="odsEmployee_Deleting"
>
<SelectParameters>
<asp:ControlParameter Name="EmployeeID" Type="Int32" Direction="Input" ControlID="listBoxEmployees" PropertyName="SelectedValue" />
</SelectParameters>
<InsertParameters>
<asp:Parameter Name="EmployeeName" Size="80" Direction = "Input" Type="String" />
</InsertParameters>
<UpdateParameters>
<asp:Parameter Name="EmployeeID" Type="Int32" Direction="Input" />
<asp:Parameter Name="EmployeeName" Size="80" Direction = "Input" Type="String" />
</UpdateParameters>
</asp:ObjectDataSource>

What I want to do after inserting a record from the FormView is to add the newly inserted record in the ListBox control and highlight it by making it the selected item. Below is how to achieve this:

Handle the Inserted event of odsForm as follows:

protected void odsForm_Inserted(object sender, ObjectDataSourceStatusEventArgs e)
{
ViewState["EmployeeID"] = e.ReturnValue;
}

This will store the employee id of the new inserted record in the view state.

And then handle the DataBound event of the ListBox as follows:

protected void listBoxEmployees_DataBound(object sender, EventArgs e)
{
if (listBoxEmployees.Items.Count > 0)
if (ViewState["EmployeeID"] != null)
{
listBoxEmployees.SelectedValue = ViewState["EmployeeID"].ToString();
}
else listBoxEmployees.SelectedIndex = 0;
ViewState.Remove("EmployeeID");
}

This will set the SelectedValue of the ListBox to the value in the view state. After we used the value in the view state, we remove it.

It works great.

The difference between Eval and Bind data binding functions in ASP.NET

When binding in ASP.NET within FormView, GridView or DetailsView, one could use data-binding expressions with this tag <%# %>. There are two functions, which are Eval and Bind, used frequently. For instance, suppose you a data source has the field named "ProductName", you could bind it as follows:

<%# Eval('ProductName')%> OR <%# Bind('ProductName')%>

So what is the difference between the two functions?
The difference is, according to MSDN, the Eval function is used to define one-way (read-only) binding. The Bind function is used for two-way (updatable) binding.

About Cullen

My photo
Christian, Father, Software Developer/Architect who enjoys technology and using it to make people's lives easier!

Followers