代码之家  ›  专栏  ›  技术社区  ›  chandmk

EditorFor()和html属性

  •  114
  • chandmk  · 技术社区  · 16 年前

    Asp。Net MVC 2.0预览版本提供了以下帮助程序

    Html.EditorFor(c => c.propertyname)
    

    如果属性名是字符串,则上述代码将呈现一个纹理框。

    我是否需要为应用程序中的每种尺寸和长度组合创建一个模板?如果是这样,默认模板就无法使用。

    20 回复  |  直到 14 年前
        1
  •  91
  •   WEFX venkateswararao    15 年前

    在MVC3中,您可以按如下方式设置宽度:

    @Html.TextBoxFor(c => c.PropertyName, new { style = "width: 500px;" })
    
        2
  •  61
  •   tjeerdhans    16 年前

    我通过在我的/Views/Shared/ReditorTemplates文件夹中创建一个名为String.ascx的EditorTemplate来解决这个问题:

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

    在我看来,我使用

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

    对我来说很有魅力!

        3
  •  33
  •   wayne.blackmon    14 年前

    在这个或任何其他关于为@HTML设置HTML属性的帖子中都没有答案。EditorFor对我帮助很大。然而,我确实在

    Styling an @Html.EditorFor helper

    我使用了相同的方法,它工作得很好,不需要编写大量额外的代码。注意html的html输出的id属性。EditorFor已设置。视图代码

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

    带有数据注释和日期格式为“dd MMM-yyyy”的模型属性

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

    无需编写大量额外代码,即可轻松工作。这个答案使用ASP。NET MVC 3 Razor C#。

        4
  •  25
  •   tj.    16 年前

    可能想看看 Kiran Chand's Blog post ,他在视图模型上使用自定义元数据,例如:

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

    这与使用元数据的自定义模板相结合。在我看来,这是一种干净简单的方法,但我希望看到mvc内置了这个常见的用例。

        5
  •  17
  •   Ishmael Smyrnow    14 年前

    我很惊讶没有人提到在“additionalViewData”中传递它并在另一边阅读它。

    视图 (为清楚起见,带换行符):

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

    编辑器模板:

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

    问题是,你的模板可以包含多个HTML元素,所以MVC不知道应该将你的大小/类应用于哪个元素。你必须自己定义它。

    让你的模板从你自己的名为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
      }
    

    }

    在模板中,您可以这样做:

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

    在你看来,你做到了:

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

    第一个表单将呈现字符串的默认模板。第二个表单将渲染自定义模板。

    使用流畅界面的替代语法:

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

    请注意,您也可以在控制器中执行此操作,而不是在视图中执行,或者在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) });
    }
    

    还请注意,您可以创建基础TemplateViewModel类——所有视图模板的共同基础——它将包含对属性等的基本支持。

    但总的来说,我认为MVC v2需要一个更好的解决方案。它仍然是Beta版——去问吧;-)

        7
  •  6
  •   Joe Kahl    14 年前

    我认为使用CSS是正确的做法。我希望我能做得更多。NET编码,就像XAML一样,但在浏览器中CSS是王道。

    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>
    

        8
  •  6
  •   Jay    10 年前

    与MVC 5一样,如果你想添加任何属性,你可以简单地做

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

    从以下位置找到的信息 this blog

        9
  •  3
  •   Carlos Fernandes    16 年前

    我不知道为什么它不适用于Html。EditorFor,但我尝试了TextBoxFor,它对我有效。

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

    …以及验证工作。

        10
  •  3
  •   spot    16 年前

    您可以为属性定义属性。

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

    这被称为 System.ComponentModel.DataAnnotations . 如果你找不到 ValidationAttribute 您可以随时定义自定义属性。

    顺致敬意, 卡洛斯

        11
  •  3
  •   chandmk    15 年前

    这可能不是最简单的解决方案,但很简单。您可以为HtmlHelper编写一个扩展。班级编辑。在该扩展中,您可以提供一个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 .

        12
  •  3
  •   Piotr Czyż    14 年前

    我写了一篇博客来回答我自己的问题

    Adding html attributes support for Templates - ASP.Net MVC 2.0 Beta

        13
  •  2
  •   Dmitry Efimenko    14 年前

    在我的实践中,我发现最好使用EditorTemplates,其中只有一个HtmlHelper——在大多数情况下是TextBox。如果我想要一个更复杂的html结构的模板,我会编写一个单独的HtmlHelper。

    假设我们可以将整个ViewData对象粘贴到TextBox的htmlAttributes中。此外,如果需要特殊处理,我们可以为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.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">
    
        14
  •  2
  •   stuartdotnet    14 年前

    因为问题在于 编者为 不是TextBoxFor 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 {
        width: 80em;
    }
    

    此外,您可以设置以下样式

    input[type="text"] {
        width: 200px;
    }
    
    • 这将覆盖.text框,并将更改所有输入文本框,EditorFor或其他。
        15
  •  2
  •   Ashish    13 年前

    我在MVC3中设置TextBox的宽度时也遇到了问题,而设置Clsss属性适用于TextArea控件,但不适用于TextBoxFor控件或EditorFor控件:

    我试着跟随&这对我很有效:

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

    在这种情况下,验证也工作得很好。

        16
  •  2
  •   Phil Cooper    13 年前

    一种解决方法是让视图模型上的委托处理打印出这样的特殊渲染。我为一个分页类做了这件事,我在模型上公开了一个公共属性 Func<int, string> RenderUrl

    因此,定义自定义位的编写方式:

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

    输出视图 Paging 类别:

    @Html.DisplayFor(m => m.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>
    }
    

    这可能会让事情变得过于复杂,但我到处都在使用这些寻呼机,无法忍受看到相同的样板代码来呈现它们。

        17
  •  1
  •   queen3    16 年前

    UPDATE:嗯,显然这行不通,因为模型是按值传递的,所以属性不会被保留;但我把这个答案作为一个想法。

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

    这个更容易,但不那么方便/灵活。

        18
  •  1
  •   Aaron    15 年前

    这是获得解决方案的最干净、最优雅/最简单的方法。

    精彩的博客文章,在编写自定义扩展/辅助方法方面没有像疯狂教授那样的混乱矫枉过正。

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

        19
  •  0
  •   Community Mohan Dere    9 年前

    我真的很喜欢@tjeerdans的答案,它利用了/Views/Shared/ReditorTemplates文件夹中名为String.ascx的EditorTemplate。这似乎是这个问题最直接的答案。但是,我想要一个使用Razor语法的模板。此外,MVC3似乎使用String模板作为默认模板(参见StackOverflow问题“ mvc display template for strings is used for integers

    @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})
    
        20
  •  0
  •   Sorangwala Abbasali    9 年前

    我解决了!!
    对于Razor,语法是:
    @Html.TextAreaFor(m=>m.Address, new { style="Width:174px" }) 这将文本区域宽度调整为我在style参数中定义的宽度。

    <%=Html.TextAreaFor(m => m.Description, new { cols = "20", rows = "15", style="Width:174px" })%>
    这就行了