[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
[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
https://www.webswapp.com/codesamples/aspnet20/dependentlists/default.aspx
Comments
Anonymous
September 14, 2009
Solution is simple. The problem is, that you have these two DropDownLists in a control such as GridView or Detailsview. Those controls load from ViewState. So, when you do an autopostbakc with dropdownlist, the ViewState for that GridView/Detailsview doesn't have all the info to Bind it's Items. So, you probably have a function in code behind, an event on SelectedIndexChanged for a DropDownList. After you do your magic in that function, just end it with simple GridView1.DataBind(). That's it!Anonymous
December 04, 2009
Thank you very much! This post was a tremendous help.Anonymous
January 20, 2010
This post helped me. Thank you very much!Anonymous
February 08, 2010
Thank you very much. This post saved a lot of time :)Anonymous
March 12, 2010
Change <%#Eval("field")%> to <%#DataBinder.Eval(Container.DataItem,"field")%>. This worked for me.Anonymous
August 15, 2010
This post helped me. Thank you very much!Anonymous
August 19, 2010
Hello, I'm getting this error message as well, however this occurs in a 3 nested gridview page that has an expand/collapse function. When I attempt to edit rows in the 3rd gridview, I get the error on the: < div id="gv2div<%# Eval("gv2Item1ID") % >" > which is the div that contains my data I'm collapsing. Changing that div to what tixseven said kinda works, in the sense that I don't have an error message anymore but I can't expand the 3rd gridview anymore (and it still collapses everything). would anyone have an idea as to how I can fix this? I described in more details the matter here: forums.asp.net/.../1591961.aspx ThanksAnonymous
May 03, 2011
use Eval(Container.Dataitem,"columname") ....................instead