Domanda

Le build di anteprima Asp.Net MVC 2.0 forniscono helper come

Html.EditorFor(c => c.propertyname)

Se il nome della proprietà è stringa, il codice sopra visualizza un texbox.

Cosa succede se desidero passare le proprietà MaxLength e Size alla casella di testo o alla mia proprietà di classe CSS?

Devo creare un modello per ogni combinazione di dimensioni e lunghezza nella mia applicazione? In tal caso, ciò non rende utilizzabili i modelli predefiniti.

È stato utile?

Soluzione 11

Ho scritto un post sul blog per rispondere alla mia domanda

Aggiunta del supporto degli attributi html per i modelli - ASP.Net MVC 2.0 Beta

Altri suggerimenti

In MVC3, è possibile impostare la larghezza come segue:

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

Ho risolto questo problema creando un EditorTemplate chiamato String.ascx nella mia cartella / 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 }) %>

A mio avviso, utilizzo

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

Funziona come un incantesimo per me!

Nessuna delle risposte in questo o in altri thread sull'impostazione degli attributi HTML per @ Html.EditorFor mi è stata di grande aiuto. Tuttavia, ho trovato un'ottima risposta su

Styling an @ Html.EditorPer helper

Ho usato lo stesso approccio e ha funzionato magnificamente senza scrivere molto codice extra. Si noti che l'attributo id dell'output html di Html.EditorFor è impostato. Il codice di visualizzazione

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

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

La proprietà del modello con annotazione dei dati e formattazione della data come " gg MMM yyyy "

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

Ha funzionato come un fascino senza scrivere un sacco di codice extra. Questa risposta utilizza ASP.NET MVC 3 Razor C #.

Potrebbe voler guardare post sul blog di Kiran Chand , usa metadati personalizzati sul modello di visualizzazione come:

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

Questo è combinato con modelli personalizzati che fanno uso dei metadati. Un approccio pulito e semplice secondo me, ma vorrei vedere questo caso d'uso comune incorporato in mvc.

Sono sorpreso che nessuno abbia parlato di averlo passato in " additionalViewData " e leggendolo dall'altra parte.

Visualizza (con interruzioni di riga, per chiarezza):

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

Modello dell'editor:

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

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

Il problema è che il tuo modello può contenere diversi elementi HTML, quindi MVC non saprà a quale applicare la tua taglia / classe. Dovrai definirlo tu stesso.

Rendi il tuo modello derivato dalla tua classe chiamata 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
  }

}

Nel modello puoi farlo:

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

A tuo avviso lo fai:

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

Il primo modulo renderà il modello predefinito per la stringa. Il secondo modulo visualizzerà il modello personalizzato.

La sintassi alternativa usa un'interfaccia 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) %>

Nota che invece di farlo nella vista, puoi farlo anche nel controller, o molto meglio nel 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) });
}

Si noti inoltre che è possibile rendere la classe TemplateViewModel di base - un terreno comune per tutti i modelli di vista - che conterrà il supporto di base per attributi / ecc.

Ma in generale penso che MVC v2 abbia bisogno di una soluzione migliore. È ancora Beta - vai a chiederlo ;-)

Penso che usare CSS sia la strada da percorrere. Vorrei poter fare di più con la codifica .NET, come in XAML, ma nel browser CSS è re.

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

Come su MVC 5, se desideri aggiungere qualche attributo puoi semplicemente farlo

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

Informazioni trovate da questo blog

Puoi definire gli attributi per le tue proprietà.

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

Questo è noto come System.ComponentModel.DataAnnotations. Se non riesci a trovare il ValidationAttribute necessario, puoi sempre definire attributi personalizzati.

I migliori saluti, Carlos

Questa potrebbe non essere la soluzione più semplice, ma è semplice. È possibile scrivere un'estensione nella classe HtmlHelper.EditorFor. In tale estensione, è possibile fornire un parametro di opzioni che scriverà le opzioni su ViewData per l'helper. Ecco un po 'di codice:

Innanzitutto, il metodo di estensione:

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

Successivamente, l'oggetto opzioni:

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

E infine, ecco la linea dal modello String.ascx:

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

Francamente, penso che questo sia chiaro e chiaro per la povera anima che deve mantenere il codice lungo la strada. Ed è facile estenderlo per varie altre informazioni che desideri trasferire ai tuoi modelli. Sta funzionando bene finora per me in un progetto in cui sto cercando di racchiudere il più possibile in un set di template per aiutare a standardizzare l'html circostante, a la http://bradwilson.typepad.com/blog/2009/10/ aspnet-MVC-2-templates-parte-5-master-page-templates.html .

Non so perché non funziona per Html.EditorFor ma ho provato TextBoxFor e ha funzionato per me.

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

... e funziona anche la validazione.

Nella mia pratica ho scoperto che è meglio usare EditorTemplates con un solo HtmlHelper - TextBox che è nella maggior parte dei casi. Se voglio un modello per una struttura html più complessa, scriverò un HtmlHelper separato.

Dato che possiamo incollare l'intero oggetto ViewData al posto di htmlAttributes di TextBox. Inoltre, possiamo scrivere un codice di personalizzazione per alcune delle proprietà di ViewData se necessitano di un trattamento speciale:

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

Di seguito sono riportati gli esempi della sintassi nella vista e l'html generato:

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

Perché la domanda è per EditorFor non TextBoxFor il suggerimento di WEFX non funziona.

Per modificare singole caselle di input, è possibile elaborare l'output del metodo EditorFor:

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

È anche possibile modificare TUTTI i tuoi EditorFors poiché risulta che MVC imposta la classe di EditorFor le caselle di testo con .text-box , quindi puoi semplicemente sovrascrivere questo stile, nel tuo foglio di stile o su la pagina.

.text-box {
    width: 80em;
}

Inoltre, puoi impostare lo stile per

input[type="text"] {
    width: 200px;
}
  • sostituisce .text-box e cambierà tutte le caselle di testo di input, EditorFor o altro.

Ho anche avuto problemi con l'impostazione della larghezza di TextBox in MVC3, mentre l'impostazione dell'attributo Clsss ha funzionato per il controllo TextArea ma non per il controllo TextBoxFor o EditorFor:

Ho provato a seguire & amp; che ha funzionato per me:

 @ Html.TextBoxFor (model = & Gt; model.Title, new {Class = & Quot; textBox & Quot ;, style = & Quot; larghezza: 90%; & Quot;} )

anche in questo caso le validazioni funzionano perfettamente.

Un modo per aggirare il problema è avere delegati nel modello di visualizzazione per gestire la stampa di rendering speciali come questo. L'ho fatto per una classe di paging, espongo una proprietà pubblica sul modello Func<int, string> RenderUrl per gestirla.

Quindi definisci come verrà scritto il bit personalizzato:

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

Visualizza la vista per la Paging classe:

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

... e per la <=> visualizzazione effettiva:

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

Potrebbe essere visto come una questione troppo complicata, ma io uso questi cercapersone ovunque e non sopporto di vedere lo stesso codice del bollettino per renderli resi.

AGGIORNAMENTO: hm, ovviamente non funzionerà perché il modello viene passato per valore, quindi gli attributi non vengono conservati; ma lascio questa risposta come idea.

Un'altra soluzione, penso, sarebbe quella di aggiungere i tuoi aiutanti TextBox / etc, che controlleranno i tuoi attributi sul modello.

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

Questo è più semplice ma non altrettanto comodo / flessibile.

Questo è il modo più pulito ed elegante / semplice per ottenere una soluzione qui.

Post di blog brillanti e nessuna eccessiva confusione nello scrivere metodi di estensione / supporto personalizzati come un professore pazzo.

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

Mi è piaciuta molto la risposta di @tjeerdans che utilizza EditorTemplate denominato String.ascx nella cartella / Views / Shared / EditorTemplates. Sembra essere la risposta più diretta a questa domanda. Tuttavia, volevo un modello usando la sintassi di Razor. Inoltre, sembra che MVC3 utilizzi il modello String come predefinito (vedere la domanda StackOverflow & Quot; il modello di visualizzazione mvc per le stringhe viene utilizzato per gli interi ") quindi è necessario imposta il modello su oggetto anziché su stringa. Il mio modello sembra funzionare finora:

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

L'ho risolto !!
Per Razor la sintassi è:
@Html.TextAreaFor(m=>m.Address, new { style="Width:174px" }) questo regola la larghezza dell'area di testo alla larghezza che ho definito nel parametro style.
Per ASPx la sintassi è:
<%=Html.TextAreaFor(m => m.Description, new { cols = "20", rows = "15", style="Width:174px" })%>
questo farà il trucco

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top