views:

571

answers:

6

I run into similar codes like this all the time in aspx pages:

<asp:CheckBox Runat="server" ID="myid" Checked='<%# DataBinder.Eval(Container.DataItem, "column").Equals(1) %>'>

I was wondering what other objects I have access to inside of that <%# %> tag. How come DataBinder.Eval() and Container.DataItem are not visible anywhere inside .CS code?

A: 

I believe you have access to anything within scope of the page class, though the results of the expression are converted to a string, so you can't embed conditional expressions the way you can with "<%" expression holes.

Here is a nice blog post which dives under the covers of the generated ASPX class.

Hope this helps.

ckramer
A: 

<%# is specific to inline ASPX databinding like the link ckramer posted suggests.

How come DataBinder.Eval() and Container.DataItem are not visible anywhere inside .CS code?

To access the binding item in codebehind you would need to set up an ItemDataBound event.

Brendan Kowitz
+7  A: 

Within <%# %> tags you have access to

  1. Anything that is visible in your code-behind class (including protected methods and properties).
  2. Anything declared on the aspx page using <@import @>.
  3. Anything passed in as the event arguments when the ItemDataBound event is fired (e.g. RepeaterItemEventArgs, DataListItemEventArgs, etc).

Container is actually a wrapper for RepeaterItemEventArgs.Item, DataListItemEventArgs.Item, etc. So you can actually access it in code behind within your ItemDataBound events as e.Item (e normally being the event arguments parameter name).

DataBinder is also accessible in code behind by using System.Web.UI.DataBinder.

On a side note, casting the Container.DataItem is preferred over using Eval. Eval uses reflection so there's an overhead there. In VB.NET it would be something like

<%#DirectCast(Container.DataItem, DataRow)("some_column")%>

Or C#

<%#((DataRow)Container.DataItem)["some_column"].ToString()%>
fung
`<%#DirectCast(Container.DataItem, DataRow)("some_column")%>` should be `<%#DirectCast(Container.DataItem, Data.DataRow)("some_column")%>` if you haven't imported the `Data` assembly in your .aspx/.ascx file
Jason
+1  A: 

ASP.NET generates a subclass of TemplateControl for each occurence of a template. Databinding statements are expressions used in a method inside that class. Thus, you can call any public/protected instance method on TemplateControl. See any example that uses XPath, as those will use the XPath and XPathSelect methods; Eval, XPath and XPathSelect are all instance methods on TemplateControl.

DataBinder is actually a separate class, and Eval is a public static method on it; it's in System.Web.UI. DataBinder.Eval and plain Eval are not directly related though they do very similar things visibly.

I believe that "Container" is actually a local variable or parameter where databinding statements are compiled. I can't remember its type at the moment.

Jesse Millikan
A: 

Great example

<%#((System.Data.DataRow)Container.DataItem)["ColumnName"].ToString()%>
A: 

using <%# %> actually means that code inside this block will execute when page.DataBind() method is being executed. Thus you can access anything at that point accessible as protected/public to that particular page/control.

Robert Koritnik