2011-03-04 20 views
59

Basit alan formu var@ Html.LabelFor şablonunu nasıl geçersiz kılabilirim?

<div class="field fade-label"> 
    @Html.LabelFor(model => model.Register.UserName) 
    @Html.TextBoxFor(model => model.Register.UserName) 
</div> 

ve bu sonuçlanır:

<div class="field fade-label"> 
    <label for="Register_UserName">Username (used to identify all services, from 4 to 30 chars)</label> 
    <input type="text" value="" name="Register.UserName" id="Register_UserName"> 
</div> 

ama LabelFor kod ben sahip sonunda böylece içinde bir <span> eklemek bunu istiyorum:

<label for="Register_UserName"> 
    <span>Username (used to identify all services, from 4 to 30 chars)</span> 
</label> 

Bunu nasıl yapabilirim?

Tüm examplesEditorTemplates kullanın, ancak bu bir LabelFor.

+0

Bu olacağına dair belirsizliklerin olası çağrı istisna neden olur. Aşırı genişletme yöntemleri yoktur. – Nilzor

+0

@Nilzor, böyle bir parametreye sahip bir uzantı yok, cevabımda kodu kullanmak güvenli, hatırlıyorum, 'LabelFor'' EditorFor' değil. – balexandre

+0

Evet, haklısınız. Söylediğim şey, yönteminizin @ Html.LabelFor (model => model.Register.UserName) yapısını geçersiz kılmamasıdır. Bu imzaya aşırı yük eklemeye çalışırsanız, test ettiğim gibi bir muğlak çağrı istisnası alırsınız. Çözümünüz sağlamdır, ancak çağrı kodunu (görünümleri) değiştirmenizi gerektirir. – Nilzor

cevap

65

Bunu, kendi HTML yardımcılarınızı oluşturarak yaparsınız.

http://www.asp.net/mvc/tutorials/creating-custom-html-helpers-cs

Sen ASP.Net MVC için kaynak indirerek LabelFor <> kodunu görüntülemek ve özel bir yardımcı olarak o değiştirebilir.


cevapbalexandre

public static class LabelExtensions 
{ 
    public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object htmlAttributes) 
    { 
     return LabelFor(html, expression, new RouteValueDictionary(htmlAttributes)); 
    } 
    public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, IDictionary<string, object> htmlAttributes) 
    { 
     ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData); 
     string htmlFieldName = ExpressionHelper.GetExpressionText(expression); 
     string labelText = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last(); 
     if (String.IsNullOrEmpty(labelText)) 
     { 
      return MvcHtmlString.Empty; 
     } 

     TagBuilder tag = new TagBuilder("label"); 
     tag.MergeAttributes(htmlAttributes); 
     tag.Attributes.Add("for", html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName)); 

     TagBuilder span = new TagBuilder("span"); 
     span.SetInnerText(labelText); 

     // assign <span> to <label> inner html 
     tag.InnerHtml = span.ToString(TagRenderMode.Normal); 

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

Anladım, kimsenin kopyalayıp/yapıştırması/kullanması için son kodu soruma ekledim. Başların için teşekkürler. – balexandre

+0

Bu uzantı yöntemini bir başlangıç ​​olarak kullandım, ama LabelNor parametresi ile LabelFor yöntemini geçersiz kılmadığından, onu biraz güncelleştirdim. –

+4

Bunu kullanırken Ambigious başlatma hatasını nasıl çözerim. şimdi, varsayılan MVC'den ve budan bir tane olmak üzere iki LabelFor yöntemi vardır. – Ruchan

2

LabelFor tarafından eklenen (statik) bir uzantısı bir yöntemdir ve bu nedenle geçersiz edilemez. İhtiyacınız olanı elde etmek için kendi Html Helper Extension yönteminizi oluşturmanız gerekir.

+2

Editör şablonları "STAT" statik olsa da "overriden" olabilir. – Linkgoron

+1

Burada Editör şablonları hakkında konuşmuyoruz. Düzenleyici şablonu, sözleşmeyle keşfedilen kısmi bir görünümdür.Bir uzantı yönteminin geçersiz kılma veya statik bildirimi ile ilgisi yoktur. –

+11

Evet, ancak birileri LabelFor'u gördükten sonra EditorFor'a benzediğini gördüğü zaman, MIGHT onun da bu kongre ile overiden olabileceğini düşünüyor. OP'nin sorduğu tam olarak buydu. Bu yöntem aşırı yükleme ve statik yöntemler ile ilgisi yoktur. – Linkgoron

2

Balealexandre'ın yanıtı üzerine genişledim ve etiket metninizi hem önce hem de sonra eklemek için HTML belirtme özelliğini ekledim. Bir sürü yöntem aşırı yükleme ve yorum ekledim. Umarım bu millet yardımcı olur!

Ayrıca buradan bilgi budaklı: imza varolan uzatma yöntemine özdeş olduğundan Html inside label using Html helper

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()); 
     } 
    } 
} 
İlgili konular