2012-10-17 14 views
21

Działa to dla chwytając nagłówki (BEZ WARTOŚCI):Wywołanie IEnumerable przeciążenie DisplayNameFor

@model IEnumerable<SomeModel> 
... 
<th>@Html.DisplayNameFor(m => m.SomeModelProperty)</th> 

Które jeśli SomeModelProperty były:

[Display(Name = "An Excellent Header")] 
SomeModelProperty { get; set; } 

Wtedy wyświetli się "doskonałą Nagłówek" w element nagłówka th.

Można by pomyśleć, to nie będzie działać, ponieważ model jest IEnumerable, który nie miałby m.SomeModelProperty, ale to działa, ponieważ HtmlHelper posiada HtmlHelper<IEnumerable<TModel>> taki sposób, że parametr lambda jest TModel nie IEnumerable<TModel>. Ponieważ to po prostu używa metadanych, nie ma potrzeby, aby element z kolekcji. (Chociaż intellisense na m. będzie cię okłamywać i sprawi, że pomyślisz, że to kolekcja). Nie jestem pewien, kiedy dodano to super przeciążenie, ale jest całkiem przydatny w przypadku Index.cshtml i rezygnuje z funky takich, jak @Html.DisplayNameFor(m => @Model.FirstOrDefault().SomeModelProperty), których chcę uniknąć.

http://msdn.microsoft.com/en-us/library/hh833697(v=vs.108).aspx

Jednak nie mogę dowiedzieć się, jak uzyskać to do pracy, kiedy mój model nie jest IEnumerable, lecz zawiera IEnumerable jako właściwości, takie jak:

public class SomeList 
{ 
    public List<SomeModel> SomeModels { get; set; } 
    public int Page { get; set; } 
    public DateTime CurrentAsOf { get; set; } 
} 

byłem mając nadzieję na wyraźne podanie ogólnych parametrów typów, ale myślę, że parametry typu są określane przez silnik, który spływa z HtmlHelpera utworzonego ze stroną. Czy mogę zadeklarować nowy HtmlHelper na stronie, czy też w jakiś sposób dokładnie określić parametry typu?

Index.cshtml:

@model SomeList 
//No idea how to do this: 
@Html.DisplayNameFor<IEnumerable<SomeModel>>(m => m.SomeModelProperty) 
+2

W swoim kodzie pętli w pliku Razor możesz sprawdzić, czy jest to ** pierwszy element w pętli, i wypisać '' używając wywołań 'DisplayNameFor'. To 'if' byłoby przed częścią, w której wypisujesz dane w' tr'. – Gromer

+1

Tak Użyłem tego typu obejść, mając nadzieję odejść od tego teraz, gdy DisplayNameFor obsługuje pobieranie metadanych z IEnumerable – AaronLS

+0

To pytanie ma dobre i działające rozwiązanie (zaakceptowana odpowiedź): http://stackoverflow.com/questions/20807869/displaynamefor-from-listobject-in-model – lxa

Odpowiedz

38

Inny podobny obejście, które działa nawet wtedy, gdy nie istnieją żadne wiersze mogą być:

... 
@{var dummy = Model.FirstOrDefault(); } 
    <tr> 
     <th> 
      @Html.DisplayNameFor(model => dummy.SomeModelProperty) 
     </th> 
... 
+4

Wywołanie jest niejednoznaczne między następującymi metodami lub właściwościami: "System.Web.Mvc.Html.DisplayNameExtensions.DisplayNameFor (System.Web.Mvc. HtmlHelper >, System.Linq.Expressions.Expression >) 'oraz' System.Web.Mvc.Html .DisplayNameExtensions.DisplayNameFor , int> ... –

+1

to samo problem jako Oleg Sh ... –

+1

Czy ktoś zdołał rozwiązać ten problem? – user3407039

5

Mam dokładnie ten sam problem, ponieważ używam ViewModels więc mam ViewModel z IEnumerable rzeczywistych obiektów jako właściwość.

Natknąłem się na ten wpis, gdzie po sprawdzeniu odpowiedzi facet stworzył własny HTMLHelper, aby rozwiązać ten problem: http://forums.asp.net/t/1783733.aspx. Jego wersja to:

public static MvcHtmlString DisplayColumnNameFor<TModel, TClass, TProperty>(
    this HtmlHelper<TModel> helper, IEnumerable<TClass> model, 
    Expression<Func<TClass, TProperty>> expression) 
{ 
    var name = ExpressionHelper.GetExpressionText(expression); 
    name = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name); 
    var metadata = ModelMetadataProviders.Current.GetMetadataForProperty(
     () => Activator.CreateInstance<TClass>(), typeof(TClass), name); 

    return new MvcHtmlString(metadata.DisplayName); 
} 

Musisz podać dwa wyliczenia i wyrazy argumentów, a nie zwykłe wyrażenie, więc możesz preferować odpowiedź @franz. Nie widzę, aby istniała i tak konieczność przekazania 2 argumentów, ponieważ musi ona wiedzieć, do której właściwości modelu widoku stosujesz wyrażenie.