it-swarm.com.de

EditorFor () - und HTML-Eigenschaften

Asp.Net MVC 2.0 Preview Builds bieten Helfer wie 

Html.EditorFor(c => c.propertyname)

Wenn der Eigenschaftsname string ist, wird im obigen Code eine Textbox dargestellt.

Was ist, wenn ich die Eigenschaften MaxLength und Size an das Textfeld oder meine eigene css-Klasseneigenschaft übergeben möchte?

Muss ich für jede Kombination aus Größe und Länge in meiner Anwendung eine Vorlage erstellen? Wenn ja, werden die Standardvorlagen dadurch nicht verwendbar.

112
chandmk

Ich habe einen Blogeintrag geschrieben, um meine eigene Frage zu beantworten

Hinzufügen von Unterstützung für HTML-Attribute für Vorlagen - ASP.Net MVC 2.0 Beta

3
chandmk

In MVC3 können Sie die Breite wie folgt einstellen:

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

Ich habe dieses Problem gelöst, indem ich in meinem Ordner/Views/Shared/EditorTemplates ein EditorTemplate mit dem Namen String.ascx erstellt habe:

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

Aus meiner Sicht benutze ich

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

Funktioniert wie ein Zauber für mich!

61
tjeerdhans

Keine der Antworten in diesem oder einem anderen Thread zum Setzen von HTML-Attributen für @ Html.EditorFor hat mir sehr geholfen. Ich fand jedoch eine großartige Antwort auf 

Einen @ Html.EditorFor-Helfer gestalten

Ich habe den gleichen Ansatz gewählt und es hat wunderbar funktioniert, ohne viel zusätzlichen Code zu schreiben. Beachten Sie, dass das ID-Attribut der HTML-Ausgabe von Html.EditorFor festgelegt ist. Der Ansichtscode

<style type="text/css">
#dob
{
   width:6em;
}
</style>

@using (Html.BeginForm())
{
   Enter date: 
   @Html.EditorFor(m => m.DateOfBirth, null, "dob", null)
}

Die Modelleigenschaft mit Datenanmerkung und Datumsformatierung als "TT MMM JJJJ"

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

Hat wie ein Zauber gearbeitet, ohne viel extra Code zu schreiben. Diese Antwort verwendet ASP.NET MVC 3 Razor C #.

33
wayne.blackmon

Vielleicht möchten Sie sich Kiran Chand's Blogbeitrag anschauen, er verwendet benutzerdefinierte Metadaten für das Ansichtsmodell wie:

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

Dies wird mit benutzerdefinierten Vorlagen kombiniert, die die Metadaten verwenden. Ein sauberer und einfacher Ansatz meiner Meinung nach, aber ich würde mir wünschen, dass dieser allgemeine Anwendungsfall in mvc integriert ist. 

25
tj.

Ich bin überrascht, dass niemand erwähnt hat, dass er in "additionalViewData" weitergegeben und auf der anderen Seite gelesen wurde.

Ansicht (mit Zeilenumbrüchen zur besseren Übersicht):

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

Editor-Vorlage:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %>

<%= Html.TextBox("", Model, ViewData["htmlAttributes"])) %>
17
Ishmael Smyrnow

Ich denke, CSS zu benutzen ist der Weg zu gehen. Ich wünschte, ich könnte mehr mit .NET-Codierung wie in XAML machen, aber im Browser ist CSS König.

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

6
Joe Kahl

Wenn Sie Attribute hinzufügen möchten, können Sie dies wie bei MVC 5 tun

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

Informationen aus diesem Blog

6
Jay

Das Problem ist, dass Ihre Vorlage mehrere HTML-Elemente enthalten kann, so dass MVC nicht wissen kann, auf welches Element Ihre Größe/Klasse angewendet werden soll. Sie müssen es selbst definieren.

Lassen Sie Ihre Vorlage von Ihrer eigenen Klasse namens TextBoxViewModel ableiten:

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
  }

}

In der Vorlage können Sie Folgendes tun:

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

Aus Ihrer Sicht tun Sie:

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

Das erste Formular rendert die Standardvorlage für Zeichenfolge. Das zweite Formular rendert die benutzerdefinierte Vorlage.

Alternative Syntax verwenden fließende Schnittstelle:

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

Beachten Sie, dass Sie dies nicht in der Ansicht tun, sondern auch im Controller oder viel besser im 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) });
}

Beachten Sie auch, dass Sie eine Basis-TemplateViewModel-Klasse erstellen können - eine gemeinsame Basis für alle Ihre Ansichtsvorlagen -, die grundlegende Unterstützung für Attribute/etc enthält.

Im Allgemeinen denke ich, dass MVC v2 eine bessere Lösung braucht. Es ist immer noch Beta - bitte fragen Sie danach ;-)

6
queen3

Sie können Attribute für Ihre Eigenschaften definieren.

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

Dies ist bekannt als System.ComponentModel.DataAnnotations. Wenn Sie die benötigte ValidationAttribute nicht finden, können Sie immer benutzerdefinierte Attribute definieren.

Beste Grüße, Carlos

3

Dies ist möglicherweise nicht die glatteste Lösung, aber es ist unkompliziert. Sie können eine Erweiterung für die HtmlHelper.EditorFor-Klasse schreiben. In dieser Erweiterung können Sie einen Optionsparameter angeben, der die Optionen für den Helper in die ViewData schreibt. Hier ist ein Code:

Zunächst die Erweiterungsmethode:

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

Als nächstes das Optionsobjekt:

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

Zum Schluss noch die Zeile aus der String.ascx-Vorlage:

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

Ehrlich gesagt denke ich, dass dies für die arme Seele unkompliziert und klar ist, die Ihren Code auf der Straße aufrechterhalten muss. Und es ist einfach für verschiedene andere Informationen, die Sie an Ihre Vorlagen weitergeben möchten, zu erweitern. Es funktioniert soweit gut für mich in einem Projekt, in dem ich versuche, so viel wie möglich in eine Reihe von Vorlagen einzuwickeln, um die umgebenden HTML-Dateien zu standardisieren, a la http://bradwilson.typepad.com/blog/ 2009/10/aspnet-mvc-2-templates-part-5-master-page-templates.html .

3
spot

Ich weiß nicht, warum es für Html.EditorFor nicht funktioniert, aber ich habe TextBoxFor ausprobiert und es hat für mich funktioniert.

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

... und auch Validierungsarbeiten.

3
Piotr Czyż

Weil die Frage für EditorFor nicht TextBoxFor ist, schlägt der Vorschlag von WEFX nicht vor. 

Zum Ändern einzelner Eingabefelder können Sie die Ausgabe der EditorFor-Methode verarbeiten:

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

Es ist auch möglich, ALLE Ihre EditorFors zu ändern, da MVC die Klasse der EditorFor-Textfelder mit .text-box festlegt. Daher können Sie diesen Stil in Ihrem Stylesheet oder auf der Seite überschreiben. 

.text-box {
    width: 80em;
}

Außerdem können Sie den Stil für festlegen

input[type="text"] {
    width: 200px;
}
  • dies überschreibt das .text-Feld und ändert alle Eingabetextfelder, EditorFor oder anders. 
2
stuartdotnet

Eine Möglichkeit, dies zu umgehen, besteht darin, Delegierte für das Ansichtsmodell zu verwenden, um das Drucken von speziellen Renderings wie diesem zu behandeln. Ich habe dies für eine Paging-Klasse gemacht. Ich mache eine öffentliche Eigenschaft für das Modell Func<int, string> RenderUrl verfügbar, um damit umzugehen.

Definieren Sie also, wie das benutzerdefinierte Bit geschrieben wird:

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

Ausgabe der Sicht für die Paging-Klasse:

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

... und für die aktuelle Paging-Ansicht:

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

Es könnte als übermäßig kompliziert angesehen werden, aber ich verwende diese Pager überall und konnte es nicht ertragen, denselben Boilerplate-Code zu sehen, um sie zu rendern.

2
Phil Cooper

Ich hatte auch ein Problem mit dem Festlegen der Breite von TextBox in MVC3, während das Einstellen des Clsss-Attributs für TextArea-Steuerelement, nicht jedoch für TextBoxFor-Steuerelement oder EditorFor-Steuerelement funktioniert:

Ich habe folgendes versucht und das hat für mich funktioniert:

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

auch in diesem Fall funktionieren Validierungen einwandfrei.

2
Ashish

In meiner Praxis habe ich festgestellt, dass es am besten ist, EditorTemplates mit nur einem HtmlHelper zu verwenden - TextBox, das in den meisten Fällen ist. Wenn ich eine Vorlage für eine komplexere HTML-Struktur haben möchte, schreibe ich einen separaten HtmlHelper.

Angenommen, wir können das gesamte ViewData-Objekt anstelle von htmlAttributes der TextBox einfügen. Darüber hinaus können wir einige Anpassungscodes für einige Eigenschaften von ViewData schreiben, wenn diese einer besonderen Behandlung bedürfen:

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

Nachfolgend finden Sie Beispiele für die Syntax in der Ansicht und das ausgegebene 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">
2
Dmitry

Dies ist der sauberste und eleganteste/einfachste Weg, um hier eine Lösung zu finden.

Brillanter Blogbeitrag und kein unordentlicher Overkill beim Schreiben von benutzerdefinierten Erweiterungs-/Hilfsmethoden wie bei einem verrückten Professor.

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

1
Aaron

UPDATE: hm, offensichtlich funktioniert das nicht, da das Modell per Wert übergeben wird und die Attribute nicht erhalten bleiben. aber ich lasse diese Antwort als eine Idee.

Ich denke, eine andere Lösung wäre, Ihre eigenen TextBox/etc-Helfer hinzuzufügen, die Ihre eigenen Attribute für das Modell prüfen.

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

Dies ist einfacher, aber nicht so praktisch/flexibel.

1
queen3

Die Antwort von @tjeerdans, die das EditorTemplate namens String.ascx im Ordner/Views/Shared/EditorTemplates verwendet, hat mir sehr gut gefallen. Es scheint die direkteste Antwort auf diese Frage zu sein. Ich wollte jedoch eine Vorlage mit Razor-Syntax. Außerdem scheint es, dass MVC3 die String-Vorlage als Standard verwendet (siehe StackOverflow-Frage " mvc-Anzeigevorlage für Zeichenfolgen wird für ganze Zahlen verwendet "). Daher müssen Sie das Modell auf Objekt statt auf Zeichenfolge setzen. Meine Vorlage scheint bisher zu funktionieren:

@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})
0
zielot

Ich habe es gelöst !!
Für Razor lautet die Syntax:
@Html.TextAreaFor(m=>m.Address, new { style="Width:174px" }) Hiermit stellen Sie die Breite des Textbereichs auf die Breite ein, die ich im style-Parameter definiert habe.
Für ASPx lautet die Syntax:
<%=Html.TextAreaFor(m => m.Description, new { cols = "20", rows = "15", style="Width:174px" })%>
das wird den Trick machen

0