Nie ma @ Html.Button!


81

to jest dziwne. Widzę odniesienia do @ Html.Button (), ale kiedy piszę, że Intellisense nie znajduje takiego pomocnika ... jest lista rozwijana, ukryte, edytory itp., Ale nie ma przycisku!

o co chodzi?


Gdzie widzisz takie odniesienia?
SLaks

1
Rozumiem potrzebę spójności, ale tak naprawdę nie ma takiej potrzeby (nie ma nic do kodowania lub ochrony przed), więc wystarczyłaby długa droga do napisania pojedynczego tagu HTML: „@ Html.Button („ myButton ”, nowy {@class = "myClass"}) 'vs' <button class = "myClass"> myButton </button> '
Nine Tails

4
@Russel - Nie zgadzam się - stworzyłem metody rozszerzające na MvcHtmlString, aby wyłączyć, ustawić tylko do odczytu i ukryć elementy DOM. Ponieważ nie ma pomocnika HTML dla przycisków, nie mogę używać moich metod rozszerzających. Stwierdzenie „nie ma potrzeby” jest nieco krótkowzroczne i prawdopodobnie naiwne.
barrypicker

Odpowiedzi:


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

1
Tak ... musieli mieć naprawdę dobry powód, inaczej byłby to ogromny błąd.
Andrei Rînea

Dzięki, byłem nad nowym projektem i zaskoczony, aby zobaczyć nie html.button
Tom Stickel

7
Jeśli chcesz użyć @Html.Button("ButtonText", new {Name = "name", Value = "value" })formatu, dodaj tę klasę:public static MvcHtmlString Button(this HtmlHelper helper, string text, object htmlAttributes) { return Button(helper, text, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)); }
Mason240

1
Dobry telefon @ Mason240. Zaktualizowałem moją odpowiedź, dodając przeciążenie, jak sugerowałeś.
jessegavin

whoa ... jak ja nigdy HtmlHelper.AnonymousObjectToHtmlAttributeswcześniej nie widziałem ?
drzaus


9

Aby rozwinąć zaakceptowaną odpowiedź , aby można było powiązać przycisk przesyłania z właściwością modelu, ale mieć inny tekst:

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

Używając następującej nieco zmodyfikowanej Buttonklasy pomocniczej :

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

8

MVC5, Bootstrap w wersji 3.2.0

Spowoduje to wygenerowanie linku, który wygląda jak przycisk.


2
co to jest „Bootstrap 3”?
ekkis

1
Przepraszam, wpisałem złe słowo. Oczywiście mam na myśli Bootstrap. Dziękuję ekkis. link
Piotr Knut

1
To nie tworzy przycisku, zamiast tego łącze, które wygląda jak przycisk.
SMUsamaShah

2
Dla mnie to się nie kompiluje, jeśli nawias otwierający nie znajduje się w tym samym wierszu co ActionLink.
GaTechThomas

GaTechThomas. Tak, to prawda. Wszystko powinno być w jednej linii. Sformatowałem go w ten sposób, aby był łatwiejszy do odczytania. Najlepiej jest stworzyć własny przycisk (lub coś innego), ale jeśli nie masz na to czasu lub nie martwisz się o jego wygląd to jest to szybkie rozwiązanie.
Piotr Knut

1

Wygląda na to, że Razor nie ma pomocnika HTML „Przycisk”. Najprawdopodobniej znajdziesz odniesienia do niestandardowego rozszerzenia pomocnika HTML.

Zobacz tutaj: http://www.asp.net/mvc/tutorials/creating-custom-html-helpers-cs


1
czy to nie wydaje się dziwne? zwłaszcza jeśli jest to trywialne, dlaczego nie dołączyć go do kompletności?
ekkis

Przeczytałem ten dokument, ale nie mogę sprawić, żeby zadziałał. Umieściłem mojego pomocnika w pliku o nazwie HtmlHelpers.cs w katalogu głównym projektu i zawiera on statyczną klasę HtmlHelpers z publiczną statyczną metodą, która zwraca ciąg znaków, którego jedynym parametrem jest „this HtmlHelper helper”. wszystko się kompiluje i .Button powinien pojawić się w Intellisense, ale tak się nie dzieje ... co jeszcze mam zrobić?
ekkis

1
czy u góry widoku umieściłeś instrukcję import dla przestrzeni nazw rozszerzenia? to jest tutaj zwykły problem. możesz chcieć upewnić się, że Twoje widoki się kompilują (kliknij prawym przyciskiem myszy projekt, wybierz opcję rozładuj. kliknij prawym przyciskiem myszy, aby edytować plik - ustaw MvcBuildViews na true. zapisz i zamknij, a następnie kliknij prawym przyciskiem myszy i przeładuj projekt i skompiluj ponownie.
Adam Tuliper - MSFT

1
utwórz folder o nazwie rozszerzenia. dodaj tam klasę htmlextensions.cs (upewniając się, że przestrzeń nazw jest poprawna), a następnie w swoim widoku użyj: @using Yourapp.Extensions także włącz MvcBuildViews za pomocą notatnika, jeśli masz problem.
Adam Tuliper - MSFT

1
Ekkis, Nie jestem pewien, co zrobiłeś ze swoim projektem, ale musisz wykonać następujące czynności, aby utworzyć HtmlHelperExtension: 1) Utwórz klasę statyczną (ja nazywam swoją HtmlHelperExtensions) 2) W ramach tej klasy utwórz metody publiczne z adnotacją <Extension ( )>, z odpowiednim podpisem. 3) Zwróć MvcHtmlString.Create (). Zobacz ten post, aby zapoznać się z użytecznym i funkcjonalnym przykładem: stackoverflow.com/questions/4896439/action-image-mvc3-razor
Ben Finkel
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.