Demo for 2-way databinding cascading lists within a FormView

Download the complete source code and data for a simplifeid version of this demo as a zip file
FormView in ReadOnly mode
Company WEBSWAPP Development Inc.
Street Address 3070 Guildford Way
Country Canada
Province/State British Columbia
City Coquitlam
Edit Insert
12345

You might have wanted to use inside a databound templated server control (e.g. the FormView or the GridView) several cascading dropdownlists. The listitems in each dropdownlist would change based on the selection of the previous dropdownlist, e.g. the city selections would change based on the province and the latter would change based on the country selection. Sounds easy? Well, you added to your webform a datasource object linked for each dropdownlist where the SelectParameters collection contains a ControlParameter pointing to the previous list.

But you encounter any of those 2 error messages:

  1. Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control
  2. 'DropDownList1' has a SelectedValue which is invalid because it does not exist in the list of items.

"What is the problem?", you ask. Well, it is not a bug by Microsoft's judgement (look at this Bug Report)

When you have a dropdownlist that is dependent on another within a FormView server control, it becomes populated on SelectedIndexChanged event of the first dropdown list. However, in this case the template was not rebound to the data, only the dropdown list. The FormView was reconstructed from the saved ViewState. This causes the error message: "Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control".

The solution is to remove the 2-way databinding from the cascading dropdownlists and replace it with customized code during processing the ItemUpdating event.

Let me expand a bit on the last sentence because people who visited the site asked for such an explanation. What are the problems again?

  1. The problem of populating the dependant lists: When one list changes the second list needs to be re-bound to the data based on the previous list selection. To do that using the BIND statement, the container must be databound. But upon postback from the first list the container is not databound rather it is reconstructed from the viewstate
  2. The problem of saving the values of the dependent lists after the user makes a selection: When updating the results without the BIND statement on the SelectedValue property of the cascading lists, you need to handle the ItemUpdating event to update the values manually to the data store.

Click on the Edit link (of the FormView display above) to activate the EditItemTemplate of the FormView. Change the country selection to watch the province/State and city selections change accordingly. Then you can view the same concepts applied to the GridView by clicking on the tab for the GridView above. The source code is available in 4 versions based on the type of datasource and the programming language that you use.

Notice that every button click on this demo posts the entire page back to the server and causes the entire screen to flash back. This distracts from the viewing experience and it has a cost on band width where the entire navigational controls are being posted back and refreshed. Compare this to the same sample but while using MS ASP.NET AJAX.

Source Code #1: Source Code for this demo using ObjectDataSource bound to the FormView in C#
Source Code #2: Source Code for this demo using ObjectDataSource bound to the FormView in VB
Source Code #3: Source Code for this demo using SqlDataSource bound to the FormView in C#
Source Code #4: Source Code for this demo using SqlDataSource bound to the FormView in VB
WEBSWAPP_BLL.Demos.cs: Source Code for the Business Logic Layer that operates this site written in C#.
SAMPLES.xsd: a dataset customized from the NorthWind database to create the demos for this website. This link has the SQL script to generate the tables that are not in NorthWind database
clsOrder.cs: Source Code for clsOrder
clsProdListItem.cs: Source Code for clsProdListItem
clsProduct.cs: Source Code for clsProduct