2011-04-18 18 views

Respuesta

19

parece un buen escenario para un ayudante de encargo:

public static class LabelExtensions 
{ 
    public static MvcHtmlString LabelFor<TModel, TProperty>(
     this HtmlHelper<TModel> htmlHelper, 
     Expression<Func<TModel, TProperty>> ex, 
     Func<object, HelperResult> template 
    ) 
    { 
     var htmlFieldName = ExpressionHelper.GetExpressionText(ex); 
     var for = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName); 
     var label = new TagBuilder("label"); 
     label.Attributes["for"] = TagBuilder.CreateSanitizedId(for); 
     label.InnerHtml = template(null).ToHtmlString(); 
     return MvcHtmlString.Create(label.ToString()); 
    } 
} 

y luego:

@Html.LabelFor(
    x => x.Name, 
    @<span>Hello World</span> 
) 

ACTUALIZACIÓN:

Para lograr lo que usted pidió en la sección de comentarios que puede intentar lo siguiente:

public static class HtmlHelperExtensions 
{ 
    public static MvcHtmlString LabelFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> ex, Func<object, HelperResult> template) 
    { 
     var htmlFieldName = ExpressionHelper.GetExpressionText(ex); 
     var propertyName = htmlFieldName.Split('.').Last(); 
     var label = new TagBuilder("label"); 
     label.Attributes["for"] = TagBuilder.CreateSanitizedId(htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName)); 
     label.InnerHtml = string.Format(
      "{0} {1}", 
      propertyName, 
      template(null).ToHtmlString() 
     ); 
     return MvcHtmlString.Create(label.ToString()); 
    } 
} 

y luego:

@Html.LabelFor(
    x => x.Name, 
    @<em>mandatory</em> 
) 
+1

@ darin-Dimitrov Ah fresco, ¿cómo puedo conseguir que escribir el nombre de la ¿propiedad? Quiero que el resultado sea Marcus

+0

@Marcus, por favor consulte mi actualización. –

+0

@ darin-dimitrov, muchas gracias por intentar ayudar, pero creo que estaba un poco confuso. El valor de etiqueta que llamé PropertyName debería ser el valor especificado en el atributo de visualización en mi propiedad o el nombre como funciona la etiqueta normal. De nuevo, gracias por ayudarnos – Marcus

2

Tendrá que escribir su propio ayudante. El helper Html.Label incorporado codifica HTML automáticamente el parámetro labelText.

2

pedí prestado a la respuesta de Darin, y se añade a la misma. Agregué capacidad para Html antes del texto de la etiqueta y html después del texto de la etiqueta. También agregué un montón de métodos de sobrecarga y comentarios.

También me dio alguna información de este post: How can I override the @Html.LabelFor template?

esperanza si ayuda a la gente.

namespace System.Web.Mvc.Html 
{ 
    public static class LabelExtensions 
    { 
     /// <summary>Creates a Label with custom Html before the label text. Only starting Html is provided.</summary> 
     /// <param name="startHtml">Html to preempt the label text.</param> 
     /// <returns>MVC Html for the Label</returns> 
     public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, Func<object, HelperResult> startHtml) 
     { 
      return LabelFor(html, expression, startHtml, null, new RouteValueDictionary("new {}")); 
     } 

     /// <summary>Creates a Label with custom Html before the label text. Starting Html and a single Html attribute is provided.</summary> 
     /// <param name="startHtml">Html to preempt the label text.</param> 
     /// <param name="htmlAttributes">A single Html attribute to include.</param> 
     /// <returns>MVC Html for the Label</returns> 
     public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, Func<object, HelperResult> startHtml, object htmlAttributes) 
     { 
      return LabelFor(html, expression, startHtml, null, new RouteValueDictionary(htmlAttributes)); 
     } 

     /// <summary>Creates a Label with custom Html before the label text. Starting Html and a collection of Html attributes are provided.</summary> 
     /// <param name="startHtml">Html to preempt the label text.</param> 
     /// <param name="htmlAttributes">A collection of Html attributes to include.</param> 
     /// <returns>MVC Html for the Label</returns> 
     public static MvcHtmlString LabelFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, Func<object, HelperResult> startHtml, IDictionary<string, object> htmlAttributes) 
     { 
      return LabelFor(html, expression, startHtml, null, htmlAttributes); 
     } 

     /// <summary>Creates a Label with custom Html before and after the label text. Starting Html and ending Html are provided.</summary> 
     /// <param name="startHtml">Html to preempt the label text.</param> 
     /// <param name="endHtml">Html to follow the label text.</param> 
     /// <returns>MVC Html for the Label</returns> 
     public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, Func<object, HelperResult> startHtml, Func<object, HelperResult> endHtml) 
     { 
      return LabelFor(html, expression, startHtml, endHtml, new RouteValueDictionary("new {}")); 
     } 

     /// <summary>Creates a Label with custom Html before and after the label text. Starting Html, ending Html, and a single Html attribute are provided.</summary> 
     /// <param name="startHtml">Html to preempt the label text.</param> 
     /// <param name="endHtml">Html to follow the label text.</param> 
     /// <param name="htmlAttributes">A single Html attribute to include.</param> 
     /// <returns>MVC Html for the Label</returns> 
     public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, Func<object, HelperResult> startHtml, Func<object, HelperResult> endHtml, object htmlAttributes) 
     { 
      return LabelFor(html, expression, startHtml, endHtml, new RouteValueDictionary(htmlAttributes)); 
     } 

     /// <summary>Creates a Label with custom Html before and after the label text. Starting Html, ending Html, and a collection of Html attributes are provided.</summary> 
     /// <param name="startHtml">Html to preempt the label text.</param> 
     /// <param name="endHtml">Html to follow the label text.</param> 
     /// <param name="htmlAttributes">A collection of Html attributes to include.</param> 
     /// <returns>MVC Html for the Label</returns> 
     public static MvcHtmlString LabelFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, Func<object, HelperResult> startHtml, Func<object, HelperResult> endHtml, IDictionary<string, object> htmlAttributes) 
     { 
      ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData); 
      string htmlFieldName = ExpressionHelper.GetExpressionText(expression); 

      //Use the DisplayName or PropertyName for the metadata if available. Otherwise default to the htmlFieldName provided by the user. 
      string labelText = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last(); 
      if (String.IsNullOrEmpty(labelText)) 
      { 
       return MvcHtmlString.Empty; 
      } 

      //Create the new label. 
      TagBuilder tag = new TagBuilder("label"); 

      //Add the specified Html attributes 
      tag.MergeAttributes(htmlAttributes); 

      //Specify what property the label is tied to. 
      tag.Attributes.Add("for", html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName)); 

      //Run through the various iterations of null starting or ending Html text. 
      if (startHtml == null && endHtml == null) tag.InnerHtml = labelText; 
      else if (startHtml != null && endHtml == null) tag.InnerHtml = string.Format("{0}{1}", startHtml(null).ToHtmlString(), labelText); 
      else if (startHtml == null && endHtml != null) tag.InnerHtml = string.Format("{0}{1}", labelText, endHtml(null).ToHtmlString()); 
      else tag.InnerHtml = string.Format("{0}{1}{2}", startHtml(null).ToHtmlString(), labelText, endHtml(null).ToHtmlString()); 

      return MvcHtmlString.Create(tag.ToString()); 
     } 
    } 
} 
+0

¿Cómo lo uso? – Terkhos

+0

Acabo de dejar el texto anterior en un archivo llamado LabelFor.cs que coloco en el directorio "Ayudantes". Se usa en cualquiera de mis Razor .cshtml utilizando el método @ Html.LabelFor(). – Setarcos

1

Con el fin de cumplir con los principios del SOC y sólidos, el código se puede mejorar con el siguiente código:

public static MvcHtmlString LabelFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> ex,bool applyStylingHtml) 
    { 
     var metadata = ModelMetadata.FromLambdaExpression(ex, htmlHelper.ViewData); 
     string displayName = metadata.DisplayName; 
     string description= metadata.Description; 
     if (String.IsNullOrEmpty(displayName)) 
     { 
      return MvcHtmlString.Empty; 
     } 

     var sb = new StringBuilder(); 
     sb.Append(displayName); 


     var htmlFieldName = ExpressionHelper.GetExpressionText(ex); 
     var propertyName = htmlFieldName.Split('.').Last(); 

     var tag = new TagBuilder("label"); 
     tag.Attributes["for"] = TagBuilder.CreateSanitizedId(htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName)); 
     tag.SetInnerText(sb.ToString()); 

     //Func<object, HelperResult> template='<em>'; 
     HtmlString nestedHtml=new HtmlString("<em>"+description+"</em>"); 
     tag.InnerHtml = string.Format(
      "{0} {1}", 
      tag.InnerHtml, 
      nestedHtml 
     ); 

     return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal)); 
    } 

luego usarlo en el código Razor:

@Html.LabelFor(m => m.Phone,true) 

Para hacer que todo sea más dinámico, el atributo de descripción se debe aplicar en la clase Model, luego HtmlHelper tomará la descripción como texto para aplicar la etiqueta Html "em":

[Display(Name ="Phone",Description = "should be included extention")] 
public string Phone { get; set; } 

Sólo una cabeza que tiene que importar el espacio de nombres HtmlHelper personalizado a la vista añadiendo:

@using yourNamespace 
Cuestiones relacionadas