mvc c# asp.net-mvc asp.net-mvc-2

c# - mvc - EditorFor() y propiedades html



html editorfor placeholder (20)

¡Lo resolví!
Para Razor, la sintaxis es:
@Html.TextAreaFor(m=>m.Address, new { style="Width:174px" }) esto ajusta el ancho del área de texto al ancho que @Html.TextAreaFor(m=>m.Address, new { style="Width:174px" }) en el parámetro de estilo.
Para ASPx, la sintaxis es:
<%=Html.TextAreaFor(m => m.Description, new { cols = "20", rows = "15", style="Width:174px" })%>
esto hará el truco

Las versiones de vista previa de Asp.Net MVC 2.0 proporcionan ayudantes como

Html.EditorFor(c => c.propertyname)

Si el nombre de la propiedad es una cadena, el código anterior representa un texbox.

¿Qué pasa si quiero pasar las propiedades MaxLength y Size al cuadro de texto o a mi propia propiedad de la clase css?

¿Necesito crear una plantilla para cada tamaño y combinación de longitud en mi aplicación? Si es así, eso no hace que las plantillas predeterminadas sean utilizables.


ACTUALIZACIÓN: hm, obviamente esto no funcionará porque el modelo se pasa por valor para que los atributos no se conserven; pero dejo esta respuesta como una idea.

Otra solución, creo, sería agregar tus propios ayudantes TextBox / etc, que verificarán tus propios atributos en el modelo.

public class ViewModel { [MyAddAttribute("class", "myclass")] public string StringValue { get; set; } } public class MyExtensions { public static IDictionary<string, object> GetMyAttributes(object model) { // kind of prototype code... return model.GetType().GetCustomAttributes(typeof(MyAddAttribute)).OfType<MyAddAttribute>().ToDictionary( x => x.Name, x => x.Value); } } <!-- in the template --> <%= Html.TextBox("Name", Model, MyExtensions.GetMyAttributes(Model)) %>

Este es más fácil pero no tan conveniente / flexible.


Como en MVC 5, si desea agregar atributos simplemente puede hacer

@Html.EditorFor(m => m.Name, new { htmlAttributes = new { @required = "true", @anotherAttribute = "whatever" } })

Información encontrada en este blog


Creo que usar CSS es el camino a seguir. Me gustaría poder hacer más con la codificación .NET, como en XAML, pero en el navegador, CSS es el rey.

Site.css

#account-note-input { width:1000px; height:100px; }

.cshtml

<div class="editor-label"> @Html.LabelFor(model => model.Note) </div> <div class="editor-field"> @Html.EditorFor(model => model.Note, null, "account-note-input", null) @Html.ValidationMessageFor(model => model.Note) </div>

Joe


El problema es que su plantilla puede contener varios elementos HTML, por lo que MVC no sabrá a cuál aplicar su tamaño / clase. Tendrás que definirlo tú mismo.

Haz que tu plantilla derive de tu propia clase llamada TextBoxViewModel:

public class TextBoxViewModel { public string Value { get; set; } IDictionary<string, object> moreAttributes; public TextBoxViewModel(string value, IDictionary<string, object> moreAttributes) { // set class properties here } public string GetAttributesString() { return string.Join(" ", moreAttributes.Select(x => x.Key + "=''" + x.Value + "''").ToArray()); // don''t forget to encode }

}

En la plantilla puedes hacer esto:

<input value="<%= Model.Value %>" <%= Model.GetAttributesString() %> />

En su opinión lo hace:

<%= Html.EditorFor(x => x.StringValue) %> or <%= Html.EditorFor(x => new TextBoxViewModel(x.StringValue, new IDictionary<string, object> { {''class'', ''myclass''}, {''size'', 15}}) %>

El primer formulario representará la plantilla predeterminada para la cadena. El segundo formulario representará la plantilla personalizada.

La sintaxis alternativa usa una interfaz fluida:

public class TextBoxViewModel { public string Value { get; set; } IDictionary<string, object> moreAttributes; public TextBoxViewModel(string value, IDictionary<string, object> moreAttributes) { // set class properties here moreAttributes = new Dictionary<string, object>(); } public TextBoxViewModel Attr(string name, object value) { moreAttributes[name] = value; return this; }

}

// and in the view <%= Html.EditorFor(x => new TextBoxViewModel(x.StringValue).Attr("class", "myclass").Attr("size", 15) %>

Tenga en cuenta que en lugar de hacer esto en la vista, también puede hacer esto en el controlador, o mucho mejor en ViewModel:

public ActionResult Action() { // now you can Html.EditorFor(x => x.StringValue) and it will pick attributes return View(new { StringValue = new TextBoxViewModel(x.StringValue).Attr("class", "myclass").Attr("size", 15) }); }

También tenga en cuenta que puede hacer una clase base de TemplateViewModel, un terreno común para todas sus plantillas de vista, que contendrá soporte básico para atributos / etc.

Pero, en general, creo que MVC v2 necesita una mejor solución. Todavía es Beta, ve y pídelo ;-)


En MVC3, puede establecer el ancho de la siguiente manera:

@Html.TextBoxFor(c => c.PropertyName, new { style = "width: 500px;" })


En mi práctica, encontré que lo mejor es usar EditorTemplates con solo un HtmlHelper en él - TextBox que es en la mayoría de los casos. Si quiero una plantilla para una estructura html más compleja, escribiré un HtmlHelper por separado.

Dado que podemos pegar todo el objeto ViewData en lugar de htmlAttributes del TextBox. Además, podemos escribir algunos códigos de personalización para algunas de las propiedades de ViewData si necesitan un tratamiento especial:

@model DateTime?

@* 1) applies class datepicker to the input; 2) applies additionalViewData object to the attributes of the input 3) applies property "format" to the format of the input date. *@

@{ if (ViewData["class"] != null) { ViewData["class"] += " datepicker"; } else { ViewData["class"] = " datepicker"; } string format = "MM/dd/yyyy"; if (ViewData["format"] != null) { format = ViewData["format"].ToString(); ViewData.Remove("format"); } } @Html.TextBox("", (Model.HasValue ? Model.Value.ToString(format) : string.Empty), ViewData)

A continuación se muestran los ejemplos de la sintaxis en la vista y el html generado:

@Html.EditorFor(m => m.Date)

<input class="datepicker" data-val="true" data-val-required="&amp;#39;Date&amp;#39; must not be empty." id="Date" name="Date" type="text" value="01/08/2012">

@Html.EditorFor(m => m.Date, new { @class = "myClass", @format = "M/dd" })

<input class="myClass datepicker" data-val="true" data-val-required="&amp;#39;Date&amp;#39; must not be empty." id="Date" name="Date" type="text" value="1/08">




Esta puede no ser la solución más hábil, pero es sencilla. Puede escribir una extensión a la clase HtmlHelper.EditorFor. En esa extensión, puede suministrar un parámetro de opciones que escribirá las opciones en ViewData para el ayudante. Aquí hay un código:

Primero, el método de extensión:

public static MvcHtmlString EditorFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, TemplateOptions options) { return helper.EditorFor(expression, options.TemplateName, new { cssClass = options.CssClass }); }

A continuación, el objeto de opciones:

public class TemplateOptions { public string TemplateName { get; set; } public string CssClass { get; set; } // other properties for info you''d like to pass to your templates, // and by using an options object, you avoid method overload bloat. }

Y finalmente, aquí está la línea de la plantilla String.ascx:

<%= Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { @class = ViewData["cssClass"] ?? "" }) %>

Francamente, creo que esto es sencillo y claro para la pobre alma que tiene que mantener tu código en el futuro. Y es fácil de ampliar para otros bits de información que le gustaría pasar a sus plantillas. Hasta ahora, está funcionando bien para mí en un proyecto en el que trato de envolver todo lo que puedo en un conjunto de plantillas para ayudar a estandarizar el html circundante, a la http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-5-master-page-templates.html .


Lo resolví creando una Plantilla de Editor llamada String.ascx en mi carpeta / Views / Shared / EditorTemplates:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %> <% int size = 10; int maxLength = 100; if (ViewData["size"] != null) { size = (int)ViewData["size"]; } if (ViewData["maxLength"] != null) { maxLength = (int)ViewData["maxLength"]; } %> <%= Html.TextBox("", Model, new { Size=size, MaxLength=maxLength }) %>

En mi opinión, yo uso

<%= Html.EditorFor(model => model.SomeStringToBeEdited, new { size = 15, maxLength = 10 }) %>

¡Funciona como un encanto para mí!


Me gustó mucho la respuesta de @tjeerdans que utiliza la Plantilla del Editor llamada String.ascx en la carpeta / Views / Shared / EditorTemplates. Parece ser la respuesta más directa a esta pregunta. Sin embargo, quería una plantilla usando la sintaxis de Razor. Además, parece que MVC3 utiliza la plantilla String como valor predeterminado (consulte la pregunta de "La plantilla de visualización mvc para cadenas se usa para enteros ") por lo que debe establecer el modelo en objeto en lugar de cadena. Mi plantilla parece estar funcionando hasta ahora:

@model object @{ int size = 10; int maxLength = 100; } @if (ViewData["size"] != null) { Int32.TryParse((string)ViewData["size"], out size); } @if (ViewData["maxLength"] != null) { Int32.TryParse((string)ViewData["maxLength"], out maxLength); } @Html.TextBox("", Model, new { Size = size, MaxLength = maxLength})


Me sorprende que nadie mencionara pasarlo en "additionalViewData" y leerlo en el otro lado.

Vista (con saltos de línea, para mayor claridad):

<%= Html.EditorFor(c => c.propertyname, new { htmlAttributes = new { @class = "myClass" } } )%>

Plantilla de editor:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %> <%= Html.TextBox("", Model, ViewData["htmlAttributes"])) %>


Ninguna de las respuestas en este o cualquier otro hilo sobre la configuración de atributos HTML para @ Html.EditorFor fue de mucha ayuda para mí. Sin embargo, encontré una gran respuesta en

Diseñando un @ Html.EditorFor helper

Usé el mismo enfoque y funcionó muy bien sin escribir mucho código adicional. Tenga en cuenta que se establece el atributo id de la salida html de Html.EditorFor. El código de vista

<style type="text/css"> #dob { width:6em; } </style> @using (Html.BeginForm()) { Enter date: @Html.EditorFor(m => m.DateOfBirth, null, "dob", null) }

La propiedad del modelo con anotación de datos y formato de fecha como "dd MMM aaaa"

[Required(ErrorMessage= "Date of birth is required")] [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd MMM yyyy}")] public DateTime DateOfBirth { get; set; }

Funcionó como un amuleto sin escribir un montón de código adicional. Esta respuesta usa ASP.NET MVC 3 Razor C #.


No sé por qué no funciona para Html.EditorFor pero probé TextBoxFor y funcionó para mí.

@Html.TextBoxFor(m => m.Name, new { Class = "className", Size = "40"})

... y también funciona la validación.


Porque la pregunta es para EditorFor no TextBoxFor la sugerencia de WEFX no funciona.

Para cambiar los cuadros de entrada individuales, puede procesar el resultado del método EditorFor:

<%: new HtmlString(Html.EditorFor(m=>m.propertyname).ToString().Replace("class=/"text-box single-line/"", "class=/"text-box single-line my500pxWideClass/"")) %>

También es posible cambiar TODOS sus EditorFors, ya que resulta que MVC establece la clase de cuadros de texto EditorFor con .text-box , por lo tanto, puede anular este estilo, en su hoja de estilo o en la página.

.text-box { width: 80em; }

Además, puedes establecer el estilo para

input[type="text"] { width: 200px; }

  • esto anula .text-box y cambiará todos los cuadros de texto de entrada, EditorFor u otros.

Puede definir atributos para sus propiedades.

[StringLength(100)] public string Body { get; set; }

Esto se conoce como System.ComponentModel.DataAnnotations . Si no puede encontrar el ValidationAttribute que necesita, siempre puede definir atributos personalizados.

Saludos cordiales, Carlos


Quisiera mirar la publicación del blog de Kiran Chand , usa metadatos personalizados en el modelo de vista como:

[HtmlProperties(Size = 5, MaxLength = 10)] public string Title { get; set; }

Esto se combina con plantillas personalizadas que hacen uso de los metadatos. Un enfoque limpio y simple en mi opinión, pero me gustaría ver este caso de uso común incorporado en mvc.


También tuve problemas para establecer el ancho de TextBox en MVC3, mientras configuraba el atributo de Clsss para el control de TextArea, pero no para el control de TextBoxFor o el control de EditorFor:

Intenté seguir y eso funcionó para mí:

@ Html.TextBoxFor (model => model.Title, new {Class = "textBox", style = "width: 90%;"})

también en este caso las validaciones funcionan a la perfección.


Una forma de evitarlo es haciendo que los delegados en el modelo de vista manejen la impresión de un renderizado especial como este. He hecho esto para una clase de búsqueda, expongo una propiedad pública en el modelo Func<int, string> RenderUrl para manejarlo.

Así que defina cómo se escribirá el bit personalizado:

Model.Paging.RenderUrl = (page) => { return string.Concat(@"/foo/", page); };

Muestra la vista para la clase de Paging :

@Html.DisplayFor(m => m.Paging)

... y para la vista de Paging real:

@model Paging @if (Model.Pages > 1) { <ul class="paging"> @for (int page = 1; page <= Model.Pages; page++) { <li><a href="@Model.RenderUrl(page)">@page</a></li> } </ul> }

Podría ser visto como una complicación excesiva, pero utilizo estos localizadores en todas partes y no podía soportar ver el mismo código repetitivo para que se renderizaran.