Свойства EditorFor () и html - PullRequest
       48

Свойства EditorFor () и html

112 голосов
/ 26 октября 2009

Предварительные сборки Asp.Net MVC 2.0 предоставляют такие помощники, как

Html.EditorFor(c => c.propertyname)

Если имя свойства является строкой, код выше отображает текстовое поле.

Что если я хочу передать свойства MaxLength и Size в текстовое поле или в свое собственное свойство класса css?

Нужно ли создавать один шаблон для каждой комбинации размера и длины в моем приложении? Если это так, то шаблоны по умолчанию не будут использоваться.

Ответы [ 20 ]

3 голосов
/ 09 апреля 2010

Возможно, это не самое приятное решение, но оно простое. Вы можете написать расширение для класса HtmlHelper.EditorFor. В этом расширении вы можете указать параметр options, который будет записывать параметры в ViewData для помощника. Вот некоторый код:

Во-первых, метод расширения:

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
    });
}

Далее объект параметров:

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.
}

И, наконец, вот строка из шаблона String.ascx:

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

Честно говоря, я думаю, что это просто и ясно для бедной души, которая должна поддерживать ваш код в будущем. И это легко расширить для различной информации, которую вы хотели бы передать своим шаблонам. Пока это хорошо работает для меня в проекте, где я пытаюсь как можно больше обернуть в набор шаблонов, чтобы помочь стандартизировать окружающий HTML, например http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-5-master-page-templates.html.

3 голосов
/ 26 октября 2009

Вы можете определить атрибуты для ваших свойств.

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

Это известно как System.ComponentModel.DataAnnotations. Если вы не можете найти ValidationAttribute, что вам нужно, вы всегда можете определить пользовательские атрибуты.

С наилучшими пожеланиями, Carlos

2 голосов
/ 25 января 2013

Один из способов обойти это - иметь делегатов в модели представления для распечатки специального рендеринга, подобного этому. Я сделал это для класса подкачки, я выставляю публичное свойство для модели Func<int, string> RenderUrl, чтобы справиться с этим.

Итак, определите, как будет записан пользовательский бит:

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

Вывести представление для класса Paging:

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

... и для фактического Paging представления:

@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>
}

Это может показаться слишком сложным делом, но я использую эти пейджеры повсюду и не могу видеть один и тот же шаблон кода для их визуализации.

2 голосов
/ 21 сентября 2012

У меня также была проблема с настройкой ширины TextBox в MVC3, хотя настройка атрибута Clsss работала для элемента управления TextArea, но не для элемента управления TextBoxFor или EditorFor:

Я попробовал следующее, и это сработало для меня:

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

также в этом случае валидации работают отлично.

2 голосов
/ 18 апреля 2012

Поскольку вопрос для EditorFor , а не TextBox для WEFX, предложение не работает.

Для изменения отдельных полей ввода вы можете обработать вывод метода EditorFor:

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

Также возможно изменить ВСЕ ваши EditorFors, поскольку выясняется, что MVC устанавливает класс текстовых полей EditorFor с помощью .text-box , поэтому вы можете просто переопределить этот стиль в своей таблице стилей или в стр.

.text-box {
    width: 80em;
}

Кроме того, вы можете установить стиль для

input[type="text"] {
    width: 200px;
}
  • это переопределяет .text-box и изменит все вводимые текстовые поля, EditorFor или иным образом.
2 голосов
/ 08 января 2012

В своей практике я обнаружил, что лучше всего использовать EditorTemplates только с одним HtmlHelper - TextBox, который в большинстве случаев. Если мне нужен шаблон для более сложной HTML-структуры, я напишу отдельный HtmlHelper.

Учитывая, что мы можем прикрепить весь объект ViewData вместо htmlAttributes TextBox. Кроме того, мы можем написать некоторый код настройки для некоторых свойств ViewData, если они нуждаются в специальной обработке:

@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)

Ниже приведены примеры синтаксиса в представлении и выведенный html:

@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">
1 голос
/ 27 октября 2009

ОБНОВЛЕНИЕ: хм, очевидно, это не будет работать, потому что модель передается по значению, поэтому атрибуты не сохраняются; но я оставляю этот ответ как идею.

Другим решением, я думаю, было бы добавление ваших собственных помощников TextBox / etc, которые будут проверять ваши собственные атрибуты на модели.

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)) %>

Это проще, но не так удобно / гибко.

1 голос
/ 17 февраля 2011

Это самый чистый и самый элегантный / простой способ получить решение здесь.

Блестящий пост в блоге и без лишних излишеств в написании пользовательских расширений / вспомогательных методов, как безумный профессор.

http://geekswithblogs.net/michelotti/archive/2010/02/05/mvc-2-editor-template-with-datetime.aspx

0 голосов
/ 23 августа 2016

Я решил это !!
Для Razor синтаксис:
@Html.TextAreaFor(m=>m.Address, new { style="Width:174px" }) это настраивает ширину текстовой области в соответствии с шириной, определенной в параметре style
Для ASPx синтаксис:
<%=Html.TextAreaFor(m => m.Description, new { cols = "20", rows = "15", style="Width:174px" })%>
это сделает свое дело

0 голосов
/ 19 июля 2012

Мне очень понравился ответ @tjeerdans, который использует EditorTemplate с именем String.ascx в папке / Views / Shared / EditorTemplates. Кажется, это самый прямой ответ на этот вопрос. Тем не менее, я хотел шаблон с использованием синтаксиса Razor. Кроме того, кажется, что MVC3 по умолчанию использует шаблон String (см. Вопрос StackOverflow " шаблон отображения mvc для строк используется для целых чисел "), поэтому вам нужно установить модель для объекта, а не для строки. Кажется, мой шаблон работает до сих пор:

@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})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...