Professor Chaos
Professor Chaos

Reputation: 9070

LabelFor() in a foreach

I have a view with a strongly-typed model associated with it

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
                  Inherits="System.Web.Mvc.ViewPage<SomeNamespace.SomeViewModel>" %>

The SomeViewModel looks like this

class SomeViewModel
{
    public IEnumerable<Foo> Foos {get; set;}
}

and say Foo is

class Foo
{
   public string Bar {get; set;}
}

and in the view

<% foreach (var item in Model.Foos) { %>
    <tr>
        <td>
            <%= Html.LabelFor(f => f.Bar) %>
        </td>

I'm not sure how to display Bar property in item using Html.LabelFor()

Can someone help me with this?

Thanks,

Upvotes: 24

Views: 15209

Answers (6)

mdm20
mdm20

Reputation: 4563

You could also just write a custom extension that's not tied directly to the Model of the page.

   public static MvcHtmlString LabelForItem<T, V>(this HtmlHelper html, T obj, Expression<Func<T, V>> expression) 
   {
       Func<T,V> func = expression.Compile();
       V val = func(obj);
       return html.Label(val.ToString());
   }

And you'd use it, like this:

@foreach (Foo foo in Model)
{
    <p>
       @(Html.LabelForItem<Foo, string>(foo, f => f.Name))
    </p>
}

Upvotes: 2

Dismissile
Dismissile

Reputation: 33071

Do this instead:

<% foreach (var item in Model.Foos) { %>      
<tr>          
    <td>              
        <%= Html.LabelFor(f => item.Bar) %>          
    </td>
<% } %>

Instead of f => f.Bar do f => item.Bar, where item is the name of the variable in your foreach loop.

Here is the much more beautiful razor syntax :)

@foreach( var item in Model.Foos ) {
<tr>
    <td>
        @Html.LabelFor(f => item.Bar)
    </td>
    <td>
        @Html.DisplayFor(f => item.Bar)
    </td>
</tr>
}

Upvotes: 48

Bob Vale
Bob Vale

Reputation: 18474

have you tried

<% for (var i=0; i<Model.Foos.Count();i++) { %> 
    <tr> 
        <td> 
            <%= Html.LabelFor(f => f.Foos[i].Bar) %> 
        </td> 

The LabelFor extension uses a lamda expression to go from your Model object to the selected property, consider f a substituion variable for your model. So you need a way to get from your model to your chosen property. You are telling LabelFor, create a local variable called f and assign it with the value of your model. then use the bit after the => to determine the target property.

If you are desperate to use the foreach, you would have to have a way of translating item back to a property of the original model, (e.g. for an array as Gledrius said x=>x.Foos[Model.Foos.IndexOf(foo)])

failing that if you just want the text value

use '<%= item %>' instead of the whole labelfor or if you have ASP.NET 4 and MVC2 or better use <%: item %> for that HTML encoding goodness

Upvotes: 2

Giedrius
Giedrius

Reputation: 8540

if Foos would be list, it would look like this:

Html.LabelFor(x=>x.Foos[Model.Foos.IndexOf(item)])

Upvotes: 0

AndrewC
AndrewC

Reputation: 6730

You are iterating over your Foo's but not using the item variable at all.

Upvotes: 0

SwDevMan81
SwDevMan81

Reputation: 50018

From here, looks like you need to specify the DisplayName on the property:

[DisplayName("My Bar")]
public string Bar { get; set; }

Upvotes: 0

Related Questions