How to loop through data in WebForms like in MVC - asp.net

How do I loop through data in WebForms like I do in ASP.NET MVC? For instance, in MVC, this is as simple as:
<table>
#foreach (var myItem in g)
{
#<tr><td>#MyItem.title<td></tr>
}
</table>
What would the code behind look like?
Or, can I add an MVC project to a WebForms application so that I can use MVC functionality, instead?

Rather than use a repeater, you can just loop through the list in a similar MVC type way using the <% %> and <%= %> tags.
<table>
<% foreach (var myItem in g) { %>
<tr><td><%= myItem.title %></td></tr>
<% } %>
</table>
As long as the property you're looping through is acessible from the aspx/ascx page (e.g. declared as protected or public) you can loop through it. There is no other code in the code behind necessary.
<% %> will evaluate the code and <%= %> will output the result.
Here is the most basic example:
Declare this list at your class level in your code behind:
public List<string> Sites = new List<string> { "StackOverflow", "Super User", "Meta SO" };
That's just a simple list of strings, so then in your aspx file
<% foreach (var site in Sites) { %> <!-- loop through the list -->
<div>
<%= site %> <!-- write out the name of the site -->
</div>
<% } %> <!--End the for loop -->

In WebForm you can use Repeater control:
<asp:Repeater id="cdcatalog" runat="server">
<ItemTemplate>
<td><%# Eval("title")%></td>
</ItemTemplate>
</asp:Repeater>
In code behind:
cdcatalog.DataSource = yourData;
cdcatalog.DataBind();

You can use a Repeater with any sort of valid DataSource (SqlDataSource, EntityDataSource, ObjectDataSource) object:
Define the DataSource
Reference the DataSource in your Reperater
....
<asp:Repeater id="someRep" runat="server" DataSourceID="YourDataSource">
<ItemTemplate>
<tr>
<td><%# Eval("PropertyName") %></td>
</tr>
</ItemTemplate>
</asp:Repeater>
...

Related

Repeater control: How to access dataitem property in itemtemplate

In Repeater control I can access the dataitem property in item template using <%# Eval("IsAvailable") %>,I want to apply if condition on IsAvailable and toggle showing div using <% %> syntax,how do I achieve that?
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<% if([IsAvailable]){ %>
<div>test1</div>
<% }else{ %>
<div>test2</div>
<% }%>
</ItemTemplate>
</asp:Repeater>

How to get the value inside a repeaters itemtemplate?

<asp:Repeater ..>
<ItemTemplate>
<% string age = Eval("a").ToString() %>
<%
age = a.ToLower(); // real stuff here
%>
<p>Hello <%# Eval("name") %> you are <%= age %> old</p>
</ItemTemplate>
</asp:Repeater>
I'm getting an error saying:
Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control.
Use <%# Eval("<propertyName>") %>
Of course you will have to assign a DataSource to your repeater, and call DataBind()
And, without using those inline coding, you can wrap the whole logic to a custom property for your data item. For example, as in the above code, you can create a custom property say, Age like:
partial class YourDataItemClass // use partial if it is auto-generated
{
public string Age
{
var ageStr = a.ToString(); // assuming YourDataItemClass has an `a` var/property
// Do real stuff here
...
...
var lowered = ageStr.ToLower();
...
...
return lowered;
}
}
and you can expose that property inside the repeater control like:
<asp:Repeater id="myRepeater" ..>
<ItemTemplate>
<p>Hello <%# Eval("Name") %> you are <%# Eval("Age") %> old</p>
</ItemTemplate>
</asp:Repeater>
Assign datasource and databind the repeater somewhere in the code-behind like:
...
// Call the method which provides you the data
// IEnumerable<YourDataItemClass> myData = ... ;
myRepeater.DataSource = myData;
myRepeater.DataBind();
...
<asp:Repeater>
<ItemTemplate>
<p>Hello <%# Eval("name") %> you are <%# Convert.ToString(Eval("a")).ToLower() %> old</p>
</ItemTemplate>
</asp:Repeater>

Repeater PageCount and PageIndex

is there pageindex or pagecount for repeater? i able to do with gridview and could not find much with repeater and not in code-behind too, how would i do PageIndex and PageCount in Repeater?
Page <%# rpt.PageIndex + 1 %> of <%# rpt.PageCount %>
<asp:Repeater ID="rpt" runat="server" OnItemCommand="rpt_OnItemCommand" OnItemDataBound="rpt_OnItemDataBound">
<HeaderTemplate>
<div >
<div >
Page <%# rpt.PageIndex + 1 %> of <%# rpt.PageCount %>
</div>
</div>
</HeaderTemplate>
<ItemTemplate ......
</asp:Repeater>
Repeater control does not support paging out of the box, which means you have to implement it yourself. One way (and the easiest probably) is to use PagedDataSource object, which encapsulates paging-related properties and logic. There is a couple of examples in web on how to accomplish this: example one, example two, example three.

How to pass custom value to asp.net control on aspx page?

I need to generate the following in ASP.NET page. What's the best, easiest way to do that?
Simplified example. So to custom property I need to pass string which would include index (i) to the property of the control. I could do it from codebehind, but it would be simpler and easier if I could keep it in .aspx file.
<table>
<%
for( var i = 0; i < 10; i++ )
{
%><tr>
<td>
<cc1:CustomControl runat="server" CustomProperty="SomeText[<% i %>]"/>
</td>
</tr>
<% } %>
</table>
Essentially I need to pass a custom, not predetermined value to the asp.net control.
This probably won't work how you expect it to. Instead, add a place holder like this:
<table>
<asp:PlaceHolder id="RowPlaceHolder" runat="server" />
</table>
And then in your code behind:
for (int i = 0;i<10;i++)
{
var tr = new HTMLTableRow();
var td = new HTMLTableCell();
var Custom = (CustomControl)LoadControl("MyControl.ascx");
Custom.id="Custom" + i.ToString();
Custom.CustomProperty = "SomeText[" + i.ToString() + "]";
td.Controls.Add(Custom);
tr.Controls.Add(td);
RowPlaceHolder.Controls.Add(tr);
}
Going deeper, if the number 10 really is hard-coded, you'll find things much easier to deal with in the long run if you just go ahead and copy 10 entries for your control into the aspx markup manually. Dynamic controls in ASP.Net webforms are rife with pitfalls and gotchas.
If the number comes from some legitimate datasource, then you're likely better off actually using that datasource and binding it to a data control like a repeater.
<%= i %>
Should work for you.
You could rock out with a repeater and use the Container.ItemIndex,
<asp:Repeater ID="rpt" runat="server">
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<cc1:CustomControl runat="server" CustomProperty="SomeText[<%# Container.ItemIndex %>]"/>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>

Passing Container.Eval to (Html.ReaderPartial) inside ASP.NET Repeater Control

I am trying to pass Eval to Html.RenderPartial inside ASP.NET Repeater but it does not work can any one help?
<asp:Repeater runat="server">
<ItemTemplate>
<% Html.RenderPartial("UserControl1",Eval("Title")); %>
</ItemTemplate>
</asp:Repeater>
by the way I know that I can do it in other ways but I want to know if it is doable or not.
is the same as in that it expects an expression that returns a string, so to get this compiling you have to call a method that calls Html.RenderPartial(), then returns an empty string:
<%
protected string RenderControl(object dataItem)
{
Html.RenderPartial("UserControl1", ((MyType) dataItem).Title);
return "";
}
%>
... <%# RenderControl(Container.DataItem) %> ...
I would just use foreach though - mixing WebForms data-binding and MVC partial rendering is unpredictable, at best:
<% foreach (MyObject o in data) { Html.RenderPartial("UserControl1", o.Title); } %>
Don't make life any harder than it needs to be...
Try putting your RenderPartial inside <%# %> statement like:
<asp:Repeater runat="server">
<ItemTemplate>
<%# Html.RenderPartial("UserControl1",Eval("Title")); %>
</ItemTemplate>
</asp:Repeater>

Resources