|
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:
- Databinding methods such as Eval(), XPath(), and Bind() can only be used in the
context of a databound control
- '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?
- 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
- 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.
|