Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databou

  • Thread starter Thread starter Owen Blacker
  • Start date Start date
O

Owen Blacker

I've spent loads of time Googling to try to work this one out and I'm
sure it's something obvious.

I get an InvalidOperationException reading "Databinding methods such as
Eval(), XPath(), and Bind() can only be used in the context of a
databound control" when I start my page. Unless I'm missing something
obvious, this is *not* the same issue as the "2-way databinding
cascading lists" issue in
http://www.webswapp.com/codesamples/aspnet20/dependentlists/default.aspx
(which is linked from everywhere; I kinda wish that were my problem ;o)

I have a templated databound custom server control, that I've built
with
a great deal of help from the two articles by 4GuysFromRolla's Scott
Mitchell (http://masl.to/?S11823B6D and http://masl.to/?P40821B6D, both
on msdn.microsoft.com).

I don't seem to be able to use databinding syntax, however:

<ItemTemplate>
<asp:TableCell runat="server"><%# Eval("First")
%></asp:TableCell>
...
</ItemTemplate>

bound to a List<Pair> gives me an exception:

[InvalidOperationException: Databinding methods such as Eval(),
XPath(),
and Bind() can only be used in the context of a databound control.]
System.Web.UI.Page.GetDataItem() +90
System.Web.UI.TemplateControl.Eval(String expression) +110
ASP.owentest_aspx.__DataBind__control8(Object sender, EventArgs e)
in
c:\Projects\Customisation\RedesignProtoTypeWeb\Owentest.aspx:13
System.Web.UI.Control.OnDataBinding(EventArgs e) +80
System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding) +198
System.Web.UI.Control.DataBind() +12
System.Web.UI.Control.DataBindChildren() +214
System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding) +208
System.Web.UI.Control.DataBind() +12
System.Web.UI.Control.DataBindChildren() +214
System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding) +208
System.Web.UI.Control.DataBind() +12
uSwitch.Web.UI.Lego.RepeatingInputRow.CreateItem(Int32 rowIndex,
Table container, Boolean useDataBinding, Object rowData) in

C:\Projects\uSwitch.Web\UI.Lego\InputModule\RepeatingInputRow.cs:361
uSwitch.Web.UI.Lego.RepeatingInputRow.CreateControlHierarchy(Boolean
useDataBinding) in

C:\Projects\uSwitch.Web\UI.Lego\InputModule\RepeatingInputRow.cs:452
uSwitch.Web.UI.Lego.RepeatingInputRow.DataBind() in

C:\Projects\uSwitch.Web\UI.Lego\InputModule\RepeatingInputRow.cs:643
Owentest.Page_Load(Object sender, EventArgs e) in

c:\Projects\Customisation\RedesignProtoTypeWeb\Owentest.aspx.cs:20
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object
o, Object t, EventArgs e) +13
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object
sender, EventArgs e) +45
System.Web.UI.Control.OnLoad(EventArgs e) +80
System.Web.UI.Control.LoadRecursive() +49
System.Web.UI.Page.ProcessRequestMain(Boolean
includeStagesBeforeAsyncPoint, Boolean
includeStagesAfterAsyncPoint) +3716

I don't get the exception if my databinding control is outside the
table
cell but, for a handful of other reasons, including that my
ItemTemplate
is being instantiated inside a TableRow, that won't work for me.

Any ideas gratefully received, as I'm completely lost.


Owen
 
Owen,

Can you post the entire page code that causes this problem?
--
HTH,
Phillip Williams
http://www.societopia.net
http://www.webswapp.com


Owen Blacker said:
I've spent loads of time Googling to try to work this one out and I'm
sure it's something obvious.

I get an InvalidOperationException reading "Databinding methods such as
Eval(), XPath(), and Bind() can only be used in the context of a
databound control" when I start my page. Unless I'm missing something
obvious, this is *not* the same issue as the "2-way databinding
cascading lists" issue in
http://www.webswapp.com/codesamples/aspnet20/dependentlists/default.aspx
(which is linked from everywhere; I kinda wish that were my problem ;o)

I have a templated databound custom server control, that I've built
with
a great deal of help from the two articles by 4GuysFromRolla's Scott
Mitchell (http://masl.to/?S11823B6D and http://masl.to/?P40821B6D, both
on msdn.microsoft.com).

I don't seem to be able to use databinding syntax, however:

<ItemTemplate>
<asp:TableCell runat="server"><%# Eval("First")
%></asp:TableCell>
...
</ItemTemplate>

bound to a List<Pair> gives me an exception:

[InvalidOperationException: Databinding methods such as Eval(),
XPath(),
and Bind() can only be used in the context of a databound control.]
System.Web.UI.Page.GetDataItem() +90
System.Web.UI.TemplateControl.Eval(String expression) +110
ASP.owentest_aspx.__DataBind__control8(Object sender, EventArgs e)
in
c:\Projects\Customisation\RedesignProtoTypeWeb\Owentest.aspx:13
System.Web.UI.Control.OnDataBinding(EventArgs e) +80
System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding) +198
System.Web.UI.Control.DataBind() +12
System.Web.UI.Control.DataBindChildren() +214
System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding) +208
System.Web.UI.Control.DataBind() +12
System.Web.UI.Control.DataBindChildren() +214
System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding) +208
System.Web.UI.Control.DataBind() +12
uSwitch.Web.UI.Lego.RepeatingInputRow.CreateItem(Int32 rowIndex,
Table container, Boolean useDataBinding, Object rowData) in

C:\Projects\uSwitch.Web\UI.Lego\InputModule\RepeatingInputRow.cs:361
uSwitch.Web.UI.Lego.RepeatingInputRow.CreateControlHierarchy(Boolean
useDataBinding) in

C:\Projects\uSwitch.Web\UI.Lego\InputModule\RepeatingInputRow.cs:452
uSwitch.Web.UI.Lego.RepeatingInputRow.DataBind() in

C:\Projects\uSwitch.Web\UI.Lego\InputModule\RepeatingInputRow.cs:643
Owentest.Page_Load(Object sender, EventArgs e) in

c:\Projects\Customisation\RedesignProtoTypeWeb\Owentest.aspx.cs:20
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object
o, Object t, EventArgs e) +13
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object
sender, EventArgs e) +45
System.Web.UI.Control.OnLoad(EventArgs e) +80
System.Web.UI.Control.LoadRecursive() +49
System.Web.UI.Page.ProcessRequestMain(Boolean
includeStagesBeforeAsyncPoint, Boolean
includeStagesAfterAsyncPoint) +3716

I don't get the exception if my databinding control is outside the
table
cell but, for a handful of other reasons, including that my
ItemTemplate
is being instantiated inside a TableRow, that won't work for me.

Any ideas gratefully received, as I'm completely lost.


Owen
 
Hi, I got the same problem and, spent about three days trying to solve it. I found that Container.DataItem works perfectly. Please if you found the solution for this problem please post it.

Here is the full code:
public class Grid : CompositeDataBoundControl, INamingContainer
{
private List<Column> columns = new List<Column>();
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[Editor(typeof(ColumnCollectionEditor), typeof(UITypeEditor))]
[PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public List<Column> Columns
{ ...}
protected override void Render(HtmlTextWriter writer)
{
writer.Write("<table border=\"1\">");
this.RenderChildren(writer);
writer.Write("</table>");
}
protected override int CreateChildControls(IEnumerable dataSource, bool dataBinding){
this.Controls.Clear();
int index = 0;
foreach (object dataItem in dataSource){
GridRow row = new GridRow(dataItem, index++, this.columns);
this.Controls.Add(row);
}
return index;
}
public override void DataBind(){
base.OnDataBinding(EventArgs.Empty);
base.DataBind();
this.DataBindChildren();
}
}

public class GridRow : CompositeControl, IDataItemContainer, INamingContainer{
public object DataItem { get; private set; }
public int DataItemIndex { get; private set; }
public int DisplayIndex { get; private set; }
private List<Column> columns;

internal GridRow(object dataItem, int index, List<Column> columns){
this.DataItem = dataItem;
this.DataItemIndex = index;
this.DisplayIndex = index;
this.columns = columns;
}
protected override void Render(HtmlTextWriter writer){
writer.Write("<tr>");
this.RenderChildren(writer);
writer.Write("</tr>");
}
protected override void CreateChildControls(){
this.Controls.Clear();
foreach (Column column in columns){
GridCell cell = new GridCell(this.DataItem, this.DataItemIndex);
this.Controls.Add(cell);
column.CellTemplate.InstantiateIn(cell);
}
}
public override void DataBind(){
base.OnDataBinding(EventArgs.Empty);
this.CreateChildControls();
this.ChildControlsCreated = true;
base.DataBind();
this.DataBindChildren();
}
}

public class GridCell : Control{
public object DataItem { get; private set; }
public int DataItemIndex { get; private set; }
public int DisplayIndex { get; private set; }

internal GridCell(object dataItem, int index)
{
this.DataItem = dataItem;
this.DataItemIndex = index;
this.DisplayIndex = index;
}

protected override void Render(HtmlTextWriter writer)
{
writer.Write("<td>");
this.RenderChildren(writer);
writer.Write("</td>");
}
}

public class Column{
public String Name { get; set; }
public String ID { get; set; }
public string Title { get; set; }

[TemplateContainer(typeof(GridRow))]
[PersistenceMode(PersistenceMode.InnerProperty)]
public ITemplate CellTemplate { get; set; }
}
<rcn:Grid ID="grd" OnGridRowDataBound="grd_GridRowDataBound" runat="server">
<rcn:Column ID="Column2" Name="Name2" Title="Name">
<CellTemplate>
<%# Eval("Name") %>
</CellTemplate>
</rcn:Column>
</rcn:Grid>
 
Back
Top