Come creare un metodo Helper HTML personalizzato DropDownFor in ASP.Net MVC

asp.net-mvc c# expression-trees html-helper lambda

Domanda

Sto provando a creare una casella a discesa che renderà un'etichetta in determinate condizioni quando l'utente non avrà accesso ad essa.

finora ho inventato questo

public static MvcHtmlString ReadOnlyCapableDropDownFor<TModel, TProperty>(
        this HtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TProperty>> expression, 
        IEnumerable<SelectListItem> selectList, 
        bool enabled, 
        object htmlAttributes
)
{
     return !enabled ? htmlHelper.DisplayFor(expression)
          : htmlHelper.DropDownListFor(expression, selectList, htmlAttributes);
}

Questo rende correttamente un'etichetta quando abilitato è falso e un elenco a discesa quando è vero, il problema è che il testo dell'etichetta è l'id del valore selezionato per l'elenco di selezione piuttosto che il testo normalmente visualizzato nel menu a discesa.

Questo ha senso perché sto usando l'espressione per il valore del display per, come faccio a usare questa espressione per ottenere il valore di testo dell'elemento di selezione selezionato piuttosto che il valore di dati?

Risposta accettata

È possibile compilare l'espressione e recuperare il valore dal modello. Quindi, scegli il testo corretto da selectList .

TProperty val = expression.Compile().Invoke(htmlHelper.ViewData.Model);
SelectListItem selectedItem = selectList.Where(item => item.Value == Convert.ToString(val)).FirstOrDefault();
string text = "";
if (selectedItem != null) text = selectedItem.Text;

return !enabled ? new MvcHtmlString("<span>" + text + "</span>")
      : htmlHelper.DropDownListFor(expression, selectList, htmlAttributes);

Penso che restituire un MvcHtmlString ad-hoc dovrebbe essere sufficiente in questo caso, dal momento che tutte le informazioni che hai sono contenute nella stringa selectList comunque. (Non è come se il tuo metodo di supporto avesse accesso a qualsiasi annotazione di dati, ecc.)


Risposta popolare

Dovrai cercare da solo il valore del testo. Dovresti essere in grado di farlo in questa routine dato che hai la lista di selezione disponibile:

? htmlHelper.DisplayFor(selectList.Single(x=>x.Value == expression).Text

anche se potrebbe essere necessario valutare l'espressione prima di utilizzarla nel codice sopra.



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché