Foreach in Markup Doesn't Recognize Loop Variable - c#

I'm using the Repeater control. All the property names in my data source are represented in my ImportColumns enum.
So I am trying to loop through the enums to pass the names to the Eval method.
This is in ItemTemplate section of my Repeater control.
Line 57: <tr class="ProductRow" data-id="<%# Eval("Id") %>">
Line 58: <% foreach (var column in (ImportColumns[])Enum.GetValues(typeof(ImportColumns))) { %>
Line 59: <td><%# Eval(column.ToString()) %></td>
Line 60: <% } %>
Line 61: </tr>
But line 59 gives me the following error.
CS0103: The name 'column' does not exist in the current context
Why doesn't the code recognize the column variable? I'm guessing it either has something to do with the fact that I'm in a repeater control or that I'm missing <% %> code and <%# %>, but it seems like this should work.
EDIT:
I see that if I change line 59.
<td><%= column.ToString() %></td>
There is no error. (Although it no longer does what I need.)
So this has something to do with Eval that prevents "regular" variables from working. Does anyone know of a workaround to this?

The column variable is not recognized because <%# ... %> data-binding expressions are evaluated when the container is data-bound, whereas <% ... %> and <%= ... %> code blocks are executed when the page is rendered. If you click "Show Complete Compilation Source" on the error page, you'll see that
foreach (var column in (ImportColumns[])Enum.GetValues(typeof(ImportColumns))) {
and
Eval(column.ToString())
are located in two separate methods.
One possible solution is to combine the loop and Eval into a single data-binding expression. For example:
<%#
string.Concat(Enum.GetValues(typeof(ImportColumns)).Cast<ImportColumns>()
.Select(column => "<td>" + Eval(column.ToString()) + "</td>"))
%>

I think what you are typing to do is use the name of the enumeration entries to be used as the property name for the Eval
If so then use the Enum.GetNames instead of the GetValues method.
Line 57: <tr class="ProductRow" data-id="<%# Eval("Id") %>">
Line 58: <% foreach (string column in Enum.GetNames(typeof(ImportColumns))) { %>
Line 59: <td><%# Eval(column) %></td>
Line 60: <% } %>
Line 61: </tr>
Edit:
You are right I didn’t test that. I also don’t use inline code so I don’t understand the intricacies. Here is a solution that works for me.
I would put that loop logic in a method in the code behind file that creates the complete row and then invoke it from the aspx page.
In the aspx
<tr class="ProductRow" data-id="<%# Eval("Id") %>">
<%# this.ColumnDetail() %>
</tr>
The method in the code behind
protected string ColumnDetail() {
string html = String.Empty;
foreach (string x in Enum.GetNames(typeof(ImportColumns))) {
html = (html + string.Format("<td>{0}</td>", Eval(x)));
}
return html;
}

Related

why aspx requires {} in if statement

I was wondering why do we have to wrap if statement with <%{%> And <%}%> for any if condition in aspx.
For example this code works:
<% if (contidtion) { %>
<%= DoSomething() %>
<%}%>
But this code doesn't work :
<% if (contidtion) { %>
<%= DoSomething()
}
%>
Can you please explain the difference between those 2 conditions. And why the first one does work and why the second one doesn't.
Looking at the definition of what the <%= %> tag does. It does the same thing as Response.Write().
https://msdn.microsoft.com/en-us/library/6dwsdcf5(VS.71).aspx
Meaning, it will output whatever the evaluated expression is inside. If you do not close the tag before if's closing "}", the "}" is considered as part of the expression inside your Response.Write(). That is why it isn't considered a closing } for the if statement.

asp tags wrapping codebehind variables

I'm trying to understand why or how to code around a problem using an if statement buried in a .aspx page using a Boolean variable that is in the page behind.
The first method works fine if I keep all everything in simple strings:
<%# (startBlock ? "<tr><td>This works</td></tr>" : "") %>
However, the second method does not work.
<% if (startBlock)
{ %>
<tr><td>This does not work</td></tr>
<td>
<asp:Label ID="Label9" Text='<%# Eval("some_variable") %>' runat="server" /></td>
</td>
<%}%>
I understand that my variable startBlock needs to be bound but adding the # symbol causes an error. How can I accomplish the second method where I need to jump in and out of code that is in the code behind the .ASPX page?
Thank you in advance.

Complex binding expression with IF on asp.net

I have a repeater with a column that I needs to have the following expression, but not sure of the syntax.
If value="DispForm.aspx" then
Show "No Document"
Else
Show the real value.
I tried to use all expresion in one line, but not sure what am I missing here
<a href=" <%# DataBinder.Eval(Container.DataItem, "Path") %>">
<%#
if (DataBinder.Eval(Container.DataItem, "FileName") == "DispForm.aspx")
{
"No document";
}
else
{
DataBinder.Eval(Container.DataItem, "FileName");}%>
</a>
Error :
http://screencast.com/t/ZERZjzZxST
It would be much simpler to use the ItemDataBound event, add an id and runat="server" to the anchor element, then you can use e.Item.FindControl("anchorname") to get the htmlanchor element. You can then set it's text, href, visibility etc. in codebehind far easier than trying to get some of the more difficult databinding logic to work effectively.
I solved it my self like this: item databound events will be fired on the server side for each row, and this report returns 2000 rows. Not a good thing.
<a href="<%# DataBinder.Eval(Container.DataItem, "fileNameUrl") %>">
<%# DataBinder.Eval(Container.DataItem, "FileName").ToString() == "DispForm.aspx" ? "No document" : DataBinder.Eval(Container.DataItem, "FileName").ToString() %>
</a>

ASP.net repeater problem

<asp:Repeater runat="server" ID="QuestionList">
<ItemTemplate>
<tr align="center">
<td><%# DataBinder.Eval(Container.DataItem, "ID") %></td>
<td><%# DataBinder.Eval(Container.DataItem, "Subject")%></td>
<td><abbr class="timeago" title="2008-07-17T09:24:17Z"><%# CommonFunctions.NiceDateTime(DataBinder.Eval(Container.DataItem, "DateSubmitted"))%></abbr></td>
<td></td>
<td><%# DataBinder.Eval(Container.DataItem, "Priority")%></td>
</tr>
</ItemTemplate>
</asp:Repeater>
My repeater works fine, but how can I format data that it uses by passing it through functions? For example the line:
CommonFunctions.NiceDateTime(DataBinder.Eval(Container.DataItem, "DateSubmitted"))
Doesn't work as container doesn't exist within current context.
It does. The following works inside an ItemTemplate for me:
<%# Server.HtmlEncode((Container.DataItem as YourFancyDataSetType).Description) %>
Of course, 'YourFancyDataSetType' could be any type. Simply convert/cast the current DataItem to the underlying type and give it to any function you may like.
#Edit: typos
First of all, I think you can use just <%# Eval("ID") %> as a shortcut for <%# DataBinder.Eval(Container.DataItem, "ID") %> and it could clean up your code a lot. There shouldn't be any problem passing the result of an Eval into a method, the Eval should get evaluated before being passed in. I believe it gets passed in as either an object or a string, though; it's been a few years since I've done that.

adding logic to datagrid item template

how would you go about adding logic to a datagrid item template? In my datagrid, i want to add a logic to it. that is, if the result for the data equals to "Yes", an "asp:label" control will be displayed; otherwise a "asp:imagebutton" control will be shown
<ItemTemplate1>
<% if DataBinder.Eval(Container.DataItem, "boflag").equals("Yes") then%>
<asp:Label id="Label1" runat="server" Text='<%# DataBinder.Eval(Container.DataItem,"boflag")%>'></asp:Label>
<% Else %>
<asp:imagebutton id="imgBtnUpdate" runat="server" NAME="Imagebutton3"
ImageUrl="no.gif"></asp:imagebutton>
<% end if %>
</ItemTemplate>
However, "<% if DataBinder.Eval(Container.DataItem,
"boflag").equals("Yes") then%> " this is not valid.
So, how can i get the data to compare the value.
Thank you
You should implement the items Data Bound Event in the code behind. Then show/hide/populate the controls there.
One other option you can do is to use a ternary operator to evaluate the boflag field and output accordingly. For example:
<%# DataBinder.Eval(Container.DataItem, "boflag").equals("Yes") ? DataBinder.Eval(Container.DataItem,"boflag") : "<input type=\"image\" src=\"\" />" %>
I'm not sure that you could add server controls through this method, but you could certainly add conditional HTML.

Categories

Resources