0

I have a peculiar case in ASP.Net Web Forms. I have a repeater in which I want to loop through a list and generate controls dynamically.

If I use <%#,

<% for (var index = 1; index < MyNamespace.Model.Count; index++)
{ %>
    <div style="font-weight: bold"><%# Eval(String.Format("v{0}_vendor_name", index.ToString())) %>: </div>
 <% } %>

I can access Eval but not my loop index variable. I get below build error:

The name 'index' doesn't exist in the current context.

If I use <%=,

 <% for (var index = 1; index < MyNamespace.Model.Count; index++)
{ %>
    <div style="font-weight: bold"><%= Eval(String.Format("v{0}_vendor_name", index.ToString())) %>: </div>
 <% } %>

I don't get any build errors, but at run-time, I get below error:

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

I have looked into a number of questions on this forum but none of them have the requirement of getting both types of variable in a single statement.

If you wonder what I'm trying to achieve, my DataTable bound to this Repeater has some dynamic columns. I want to add them dynamically depending on the count. So, my Eval should pick up v1_vendor_name, v2_vendor_name, if there are 2 columns.

I have v1_vendor_name, v2_vendor_name in the DataTable bound to this Repeater; Instead of using Eval("v1_vendor_name") and Eval("v2_vendor_name"), I'm trying to use a loop so the column in Eval is dynamically applied. I have to do this dynamically since I have no control over the number of columns. It could go up to v10_vendor_name.

I have tried using a property from code behind, as suggested by @tweray,

 for (this.index = 1; this.index < MyNamespace.Model.Count; this.index++)
   { %>
  <div style="font-weight: bold"><%# Eval(String.Format("v{0}_vendor_name", this.index.ToString())) %>: </div>
 <% } %>

But, this.index in eval always takes 0 even though I assigned 1 in the loop.

mason
  • 31,774
  • 10
  • 77
  • 121
techspider
  • 3,370
  • 13
  • 37
  • 61
  • Why not use a nested repeater? Or if you're able to, switch to ASP.NET MVC with the Razor view engine where this is all much cleaner and prettier looking. – mason Feb 17 '17 at 19:04
  • @mason - Yes, It works in MVC. But, I have to plug-in a change to an existing Web Form application. How do you think a nested repeater works? – techspider Feb 17 '17 at 19:39

2 Answers2

0

It apparently is not similar to MVC to loop through in Repeater with Bind variables.

When there is a bind variable in Repeater, it expects that field to be present in the data set bound to that control irrespective of conditions present in HTML. It doesn't pre-validate conditions.

For this scenario, I changed my data set to multiple rows instead of dynamic columns and handled with a nested repeater.

techspider
  • 3,370
  • 13
  • 37
  • 61
-1

I think you are misunderstanding the use of Eval(), look at this answer to find what is Eval() use for.

That beign said, if your remove Eval from your code, you should be good to go:

<% for (var index = 1; index < 3; index++)
{ %>
    <div style="font-weight: bold"><%= String.Format("v{0}_vendor_name", index.ToString()) %>: </div>
<% } %>
Community
  • 1
  • 1
Enrique Zavaleta
  • 2,098
  • 3
  • 21
  • 29
  • That will print a static output "v1_vendor_name", "v2_vendor_name" etc... I want `Eval("v1_vendor_name")` and `Eval("v2_vendor_name")` at runtime. Column names need to be passed to `Eval` dynamically to get value inside the corresponding column from my bound data – techspider Feb 17 '17 at 18:14
  • Did you try to change my `hard-coded 3` for your `MyNamespace.Model.Count`? – Enrique Zavaleta Feb 17 '17 at 18:16
  • Problem with your code is at `<%= String.Format("v{0}_vendor_name", index.ToString()) %>` – techspider Feb 17 '17 at 18:16
  • What problem exactly? does it crash? I just remove the Eval() and replace your Model for a fixed number – Enrique Zavaleta Feb 17 '17 at 18:20