[ASPNET]"System.InvalidOperationException: Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control." error in nested databinding scenario

 

Problem:

When you use GridView/DetailsView like template databound control to display data, and their bound template(such as Itemtemplate, Edittemplate) contains nested controls which will also bind to some other datasource controls(or perform databind operation out of the databinding context of the container control), you will probably receive the following exception

 

System.InvalidOperationException: Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control.

 

For example, if the page contains such a DetailsView below, which contains DropDownList that bound to a own DatasourceControl. If you Call this DropDownList.DataBind method in its “SelectedIndexChanged” event, the above exception will occur.

 

  <asp:TemplateField HeaderText="ItemType"

SortExpression="ItemType ">

                <InsertItemTemplate>

                    <asp:DropDownList ID="DropDownList1" runat="server"

                        DataSourceID="SqlDataSource1"

DataTextField="MyItemType" AutoPostBack="True"

                        DataValueField="MyItemType" SelectedValue='<%# Bind("MyItemType") %>'

                       

OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">

                    </asp:DropDownList>

                </InsertItemTemplate>

      

 

    </asp:DetailsView>

 

Cause:

The cause here is very simple, there is a <%# Bind...%> databinding expression in Dropdownlist here:

 

SelectedValue='<%# Bind("MyItemType") %>'

 

It is supported by the container DetailsView control(when it is performing databinding). However, when you call DropDownList.DatdBind, this expression is also evaluated, and since this time it is out of the container DetailsView’s databinding context, the exception will get raised.

 

Resolution:

For such scenario, we can consider the following resolutions:

 

1.    For inner nested controls, instead of databinding, we use other methods to populate its items. For example, we can use a for loop to add items into the dropdownlist instead of databinding. Thus, the <%# ...%> expression will not be evaluated.

 

2.    We can also perform change on the container DetailsView control. Instead of <%# %> expression, we can manually use some event such as “RowDataBound” to populate data item to the certain inner control. And when perform updating/inserting, manually extract the values from controls in the proper event(such as ItemUpdating or ItemInserting...).

 

Here is a very good article explaining this resolution:

 

#Demo for 2-way databinding cascading lists within a FormView

http://www.webswapp.com/codesamples/aspnet20/dependentlists/default.aspx