¡No hay @ Html.Button!

81

esto es raro. Veo referencias para @ Html.Button () pero cuando escribo que Intellisense no encuentra un ayudante ... hay una lista desplegable, oculta, editores, etc., ¡pero no hay botón!

¿Que pasa con eso?

ekkis
fuente
¿Dónde ves esas referencias?
SLaks
1
Entiendo el deseo de coherencia, pero realmente no hay necesidad de una (nada contra qué codificar o protegerse), por lo que todo lo que sería una forma de escribir una sola etiqueta html: '@ Html.Button ("myButton", nuevo {@class = "myClass"}) 'vs' <button class = "myClass"> myButton </button> '
Nine Tails
4
@Russel - No estoy de acuerdo - He creado métodos de extensión en MvcHtmlString para deshabilitar, hacer de solo lectura y ocultar elementos DOM. Como no hay ayuda de HTML para los botones, no puedo usar mis métodos de extensión. Decir 'no es necesario' es un poco miope y posiblemente ingenuo.
barrypicker

Respuestas:

69
public static class HtmlButtonExtension 
{

  public static MvcHtmlString Button(this HtmlHelper helper, 
                                     string innerHtml, 
                                     object htmlAttributes) 
  { 
    return Button(helper, innerHtml,
                  HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)
    ); 
  }

  public static MvcHtmlString Button(this HtmlHelper helper, 
                                     string innerHtml,
                                     IDictionary<string, object> htmlAttributes)
  {
      var builder = new TagBuilder("button");
      builder.InnerHtml = innerHtml;
      builder.MergeAttributes(htmlAttributes);
      return MvcHtmlString.Create(builder.ToString());
  }
}
jessegavin
fuente
1
Sí ... deben haber tenido una muy buena razón, de lo contrario sería un gran error.
Andrei Rînea
Gracias, estaba en un nuevo proyecto y me sorprendió no ver ningún botón html.
Tom Stickel
7
Si desea utilizar el @Html.Button("ButtonText", new {Name = "name", Value = "value" })formato, agregue esta clase:public static MvcHtmlString Button(this HtmlHelper helper, string text, object htmlAttributes) { return Button(helper, text, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)); }
Mason240
1
Buena llamada @ Mason240. Actualicé mi respuesta con una sobrecarga como sugirió.
jessegavin
whoa ... ¿cómo nunca he visto HtmlHelper.AnonymousObjectToHtmlAttributesantes?
drzaus
9

No hay ningún botón auxiliar a partir de la vista previa de mvc 3 (no mvc3)

se mencionó un montón en el pasado, por ejemplo: http://blog.wekeroad.com/blog/aspnet-mvc-preview-using-the-mvc-ui-helpers/ sin embargo, rodar el tuyo es trivial: tengo una base para ello en algún lugar por aquí tendré que desenterrarlo, pero esencialmente solo crear un nuevo Html.ButtonFor y copiar el código fuente de Html.LabelFor y cambiar la salida para crear una etiqueta input type = "button".

Adam Tuliper - MSFT
fuente
9

Para ampliar la respuesta aceptada , de modo que pueda vincular un botón de envío a una propiedad del modelo pero tener un texto diferente:

@Html.ButtonFor(m => m.Action, Model.LabelForCurrentAction(), new { @class = "btn btn-primary btn-large", type = "submit" })

Usando la siguiente clase auxiliar ligeramente modificadaButton :

/// <summary>
/// Via /programming/5955571/theres-no-html-button
/// </summary>
public static class HtmlButtonExtension
{

    public static MvcHtmlString Button(this HtmlHelper helper, object innerHtml, object htmlAttributes)
    {
        return helper.Button(innerHtml, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
    }

    public static MvcHtmlString Button(this HtmlHelper helper, object innerHtml, IDictionary<string, object> htmlAttributes)
    {
        var builder = new TagBuilder("button") { InnerHtml = innerHtml.ToString() };
        builder.MergeAttributes(htmlAttributes);
        return MvcHtmlString.Create(builder.ToString());
    }

    public static MvcHtmlString ButtonFor<TModel, TField>(this HtmlHelper<TModel> html,
                                                        Expression<Func<TModel, TField>> property,
                                                        object innerHtml,
                                                        object htmlAttributes)
    {
        // lazily based on TextAreaFor

        var attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

        var name = ExpressionHelper.GetExpressionText(property);
        var metadata = ModelMetadata.FromLambdaExpression(property, html.ViewData);

        string fullName = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);

        ModelState modelState;
        if (html.ViewData.ModelState.TryGetValue(fullName, out modelState) && modelState.Errors.Count > 0)
        {
            if( !attrs.ContainsKey("class") ) attrs["class"] = string.Empty;
            attrs["class"] += " " + HtmlHelper.ValidationInputCssClassName;
            attrs["class"] = attrs["class"].ToString().Trim();
        }
        var validation = html.GetUnobtrusiveValidationAttributes(name, metadata);
        if(null != validation) foreach(var v in validation) attrs.Add(v.Key, v.Value);

        string value;
        if (modelState != null && modelState.Value != null)
        {
            value = modelState.Value.AttemptedValue;
        }
        else if (metadata.Model != null)
        {
            value = metadata.Model.ToString();
        }
        else
        {
            value = String.Empty;
        }

        attrs["name"] = name;
        attrs["Value"] = value;
        return html.Button(innerHtml, attrs);
    }
}
drzaus
fuente
8

MVC5, Bootstrap versión 3.2.0

@Html.ActionLink
(
    linkText: " Remove", 
    actionName: "Index", 
    routeValues: null, // or to pass some value -> routeValues: new { id = 1 },
    htmlAttributes: new { @class = "btn btn-success btn-sm glyphicon glyphicon-remove" }
)

Esto generará un enlace que parece un botón.

Piotr Knut
fuente
2
¿Qué es "Bootstrap 3"?
ekkis
1
Lo siento, escribí la palabra incorrecta. Por supuesto, me refiero al Bootstrap. Gracias ekkis. enlace
Piotr Knut
1
Esto no crea un botón, sino un enlace que parece un botón.
SMUsamaShah
2
Para mí, esto no se puede compilar si el paréntesis de apertura no está en la misma línea que ActionLink.
GaTechThomas
GaTechThomas. Sí, es verdad. Todo debería estar en una línea. Lo reformateé de esta manera para que fuera más fácil de leer. Lo mejor es crear tu propio botón (o algo más), pero si no tienes tiempo para hacerlo o no te preocupa su apariencia esa es una solución rápida.
Piotr Knut
1

Razor no parece tener un ayudante HTML "Botón". Es probable que encuentre referencias a una extensión de ayuda HTML personalizada.

Vea aquí: http://www.asp.net/mvc/tutorials/creating-custom-html-helpers-cs

Ben Finkel
fuente
1
¿No parece extraño? especialmente si es trivial, ¿por qué no incluirlo para que esté completo?
ekkis
He leído ese documento pero no puedo hacerlo funcionar. He colocado mi ayudante en un archivo llamado HtmlHelpers.cs en la raíz del proyecto y contiene una clase estática HtmlHelpers con un método estático público que devuelve una cadena cuyo único parámetro es "este ayudante HtmlHelper". todo se compila y el .Button debería aparecer en Intellisense pero no lo hace ... ¿qué más se supone que debo hacer?
ekkis
1
¿Incluyó la declaración de importación para su espacio de nombres de extensión en la parte superior de su vista? ese es el problema habitual aquí. es posible que desee asegurarse de que sus puntos de vista de compilación (clic derecho en el proyecto, seleccione de descarga botón derecho del ratón para editar el archivo -.. conjunto MvcBuildViews a cierto guardar y cerrar, y el proyecto de clic y recarga la derecha y compilar de nuevo.
Adam Tuliper - MSFT
1
crea una carpeta llamada extensiones. agregue la clase htmlextensions.cs allí (asegurándose de que el espacio de nombres sea correcto) y luego, en su vista, use: @using Yourapp.Extensions también habilite MvcBuildViews usando el bloc de notas si tiene un problema.
Adam Tuliper - MSFT
1
Ekkis, no estoy seguro de lo que ha hecho con su proyecto, pero debe hacer lo siguiente para crear una HtmlHelperExtension: 1) Crear una clase estática (yo llamo a la mía HtmlHelperExtensions) 2) Dentro de esa clase, hacer métodos públicos, anotados como <Extensión ( )>, con la firma correspondiente. 3) Devuelve MvcHtmlString.Create (). Vea esta publicación para obtener un ejemplo útil y funcional: stackoverflow.com/questions/4896439/action-image-mvc3-razor
Ben Finkel