如何将Bootstrap下拉样式应用于ASP.NET MVC DropDownList?

41

以下是创建下拉列表的MVC Razor代码:

@Html.DropDownList("MyTestList", null, new { @class = "btn btn-default dropdown-toggle" })

这将创建以下下拉列表:

dropdown

使用来自getbootstrap.com的代码时:

<div class="dropdown">
    <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown">
        Dropdown
        <span class="caret"></span>
    </button>
    <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
        <li role="presentation"><a role="menuitem" tabindex="-1" href="#">test1</a></li>
        <li role="presentation"><a role="menuitem" tabindex="-1" href="#">test2</a></li>
    </ul>
</div>

它将显示下拉菜单,如下图所示:

image

问题: 当使用@Html.DropDownList时,是否可能获得与使用MVC中的HTML代码相同的外观和感觉?


类似于 Html.DropDownList 的扩展方法将有助于创建所需的 HTML 输出。 - yW0K5o
我使用了相同的代码,但它在我的电脑上无法运行。我在<head>标签中引入了bootstrap,并添加了以下代码:<div class="dropdown"> <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown"> Dropdown <span class="caret"></span> </button> <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1"> <li role="presentation"><a role="menuitem" tabindex="-1" href="#">test1</a></li> </ul> </div> 你知道为什么吗? - Ahmed Hussein
8个回答

58

这是非常可行且非常简单的。请阅读: DropDownList bootstrap styling

你所需要做的仅仅是:

@Html.DropDownList("movieGenre", "All", new { @class = "form-control"})
或者
@Html.DropDownListFor(model => model.MovieGenreModel, SelectList, new { @class = "form-control"})

4
我不敢苟同。添加 form-control 类将只会创建一个本地的、半样式化的下拉框,而这正是原帖所说想要避免的。我已经更新了我的答案,并提供了一个可行的示例。 - Joseph Woodward
你如何使用Razor创建下拉菜单? - nPcomp
这个很好用。请注意,预生成的代码可能看起来像@Html.EditorFor(model => model.MovieGenreModel, new { htmlAttributes = new { @class = "form-control" } })。如果你只是将Html.EditorFor更改为Html.DropDownListFor并放入你的SelectList,它不会起作用。你还需要确保摆脱new { htmlAttributes}这一部分。 - Tahari

54

使用Razor的@Html.DropDownList()方法无法创建你所提到的Bootstrap下拉菜单。不过,很容易创建自己的HTML助手,渲染必要的代码来创建上述下拉菜单。

有很多教程和指南(例如这个),可以带领你完成创建自定义HTML助手的过程。它们真的不难创建,并且可以加快开发速度并鼓励代码重用。

更新:

考虑到这个问题正在引起越来越多的关注以及下面(错误的)答案收到的赞数,这里提供一个(一年半了!)长期拖欠的代码示例和图片以演示它们之间的区别。

您可以将此代码复制粘贴到解决方案中,它应该能够正常工作。

enter image description here

代码:

public class BootstrapHtml
{
    public static MvcHtmlString Dropdown(string id, List<SelectListItem> selectListItems, string label)
    {
        var button = new TagBuilder("button")
        {
            Attributes =
            {
                {"id", id},
                {"type", "button"},
                {"data-toggle", "dropdown"}
            }
        };

        button.AddCssClass("btn");
        button.AddCssClass("btn-default");
        button.AddCssClass("dropdown-toggle");

        button.SetInnerText(label);
        button.InnerHtml += " " + BuildCaret();

        var wrapper = new TagBuilder("div");
        wrapper.AddCssClass("dropdown");

        wrapper.InnerHtml += button;
        wrapper.InnerHtml += BuildDropdown(id, selectListItems);

        return new MvcHtmlString(wrapper.ToString());
    }

    private static string BuildCaret()
    {
        var caret = new TagBuilder("span");
        caret.AddCssClass("caret");

        return caret.ToString();
    }

    private static string BuildDropdown(string id, IEnumerable<SelectListItem> items)
    {
        var list = new TagBuilder("ul")
        {
            Attributes =
            {
                {"class", "dropdown-menu"},
                {"role", "menu"},
                {"aria-labelledby", id}
            }
        };

        var listItem = new TagBuilder("li");
        listItem.Attributes.Add("role", "presentation");

        items.ForEach(x => list.InnerHtml += "<li role=\"presentation\">" + BuildListRow(x) + "</li>");

        return list.ToString();
    }

    private static string BuildListRow(SelectListItem item)
    {
        var anchor = new TagBuilder("a")
        {
            Attributes =
            {
                {"role", "menuitem"},
                {"tabindex", "-1"},
                {"href", item.Value}
            }
        };

        anchor.SetInnerText(item.Text);

        return anchor.ToString();
    }
}

用法:

@using (Html.BeginForm("", "", FormMethod.Post))
{

    var items = new List<SelectListItem>()
    {
        new SelectListItem() { Text = "Item 1", Value = "#" },
        new SelectListItem() { Text = "Item 2", Value = "#" },
    };

    <div class="form-group">
        @Html.Label("Before", new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.DropDownList("Name", items, "Dropdown", new { @class = "form-control"})
        </div>
    </div>

    <br/>
    <br/>
    <br/>

    <div class="form-group">
        @Html.Label("After", new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @BootstrapHtml.Dropdown("dropdownMenu1", items, "Dropdown")
        </div>
    </div>

}

1
我通常会尽可能的包含代码示例,但这一次我时间很紧。如果有一个代码示例可以帮助你,那么我很乐意为你准备并更新答案,好吗? - Joseph Woodward
老实说,我不介意跟随链接并自行获取,但我认为添加代码会对其他人有所帮助。 - matt.
1
@ᴉʞuǝ 我更新了我的答案,提供了一个代码示例。有点晚了,但迟到总比不到好! - Joseph Woodward
如果您在编辑后对此进行了一些不稳定的投票,那会更好,因为那是我试图通过移动应用程序删除我的反对票,但遇到了麻烦。现在我给你+1。 - matt.
@JosephWoodward 谢谢你的努力!你的代码示例很有帮助。 - Uğur Aldanmaz
显示剩余4条评论

8
@using (Html.BeginForm("Index", "ELibrary"))
{
@Html.DropDownListFor(m => m.Status, new SelectList(Model.StatusItems, "key", "value"), "-- Status --", new { onchange = "this.form.submit();", @class = "form-control" })
}

你只需要添加 @class="form-control" 。这很好用。但是我还将其包含在 Html.Begin form() 中。

3

如果有人在寻找.Net Core的实现方式,我已经按照Joseph Woodward的回答进行了调整。

public class BootstrapHtml
{
    public static HtmlString Dropdown(string id, List<SelectListItem> selectListItems, string label)
    {
        var button = new TagBuilder("button")
        {
            Attributes =
            {
                {"id", id},
                {"type", "button"},
                {"data-toggle", "dropdown"}
            }
        };

        button.AddCssClass("btn");
        button.AddCssClass("btn-default");
        button.AddCssClass("dropdown-toggle");

        //button.SetInnerText(label);
        button.InnerHtml.Append(" " + label);
        button.InnerHtml.AppendHtml(BuildCaret());

        //button.InnerHtml += " " + BuildCaret();

        var wrapper = new TagBuilder("div");
        wrapper.AddCssClass("dropdown");

        wrapper.InnerHtml.AppendHtml(button);
        wrapper.InnerHtml.AppendHtml(BuildDropdown(id, selectListItems));

        //wrapper.InnerHtml += button;
        //wrapper.InnerHtml += BuildDropdown(id, selectListItems);

        using (var writer = new System.IO.StringWriter())
        {
            wrapper.WriteTo(writer, HtmlEncoder.Default);
            string asd = writer.ToString();
            return new HtmlString(writer.ToString());
        }
    }

    private static TagBuilder BuildCaret()
    {
        var caret = new TagBuilder("span");
        caret.AddCssClass("caret");

        return caret;
    }

    private static TagBuilder BuildDropdown(string id, IEnumerable<SelectListItem> items)
    {
        var list = new TagBuilder("ul")
        {
            Attributes =
            {
                {"class", "dropdown-menu"},
                {"role", "menu"},
                {"aria-labelledby", id}
            }
        };

        var listItem = new TagBuilder("li");
        listItem.Attributes.Add("role", "presentation");

        foreach (var item in items)
        {
            list.InnerHtml.AppendHtml("<li role=\"presentation\">" + BuildListRow(item) + "</li>");
        }
        //items.ForEach(x => list.InnerHtml += "<li role=\"presentation\">" + BuildListRow(x) + "</li>");

        return list;
    }

    private static string BuildListRow(SelectListItem item)
    {
        var anchor = new TagBuilder("a")
        {
            Attributes =
            {
                {"role", "menuitem"},
                {"tabindex", "-1"},
                {"href", item.Value}
            }
        };
        var span = new TagBuilder("span");
        span.InnerHtml.Append(item.Text);
        anchor.InnerHtml.AppendHtml(span);
        //anchor.SetInnerText(item.Text);

        using (var writer = new System.IO.StringWriter())
        {
            anchor.WriteTo(writer, HtmlEncoder.Default);
            string asd = writer.ToString();
            return writer.ToString();
        }
    }
}

1

Try this code :

  @Html.DropDownListFor(model => model.MovieGenreModel, SelectList,
                   new { @class = "form-control",aria_describedby="dropdownMenu1"})

0

我已经在ASP.net MVC中使用一个实际的例子成功地实现了Bootstrap按钮,在我的当前工作地点正在使用。

<div class="dropdown" style="display:inline-block">
            <button class="btn btn-warning dropdown-toggle" type="button" data-toggle="dropdown" value="@Model.Id"  runat="server"><span class="glyphicon glyphicon-user"></span> Assign <span class="caret"></span></button>
            <ul class="dropdown-menu" onclick="location.href='@Url.Action("AssignTicket", "Home", new {AssignId = Model.Id })'">
                @foreach (var user in (IEnumerable<SelectListItem>)ViewBag.User)
                {
                    <li>@user.Text</li>
                }
            </ul>
</div>

View.user 是直接从数据库中获取用户的名称。 希望这是你们中一些人正在寻找的。


0

在进行长时间搜索后,我需要使用JQuery动态添加class属性,如下所示:

$(document).ready(function(){
   $("select").last().addClass("form-control");
});

-1

@Html.DropDownListFor 中添加 @class = "form-control" 是无效的。也就是说,您可以通过复制其他 "form-control" 输入的样式(例如通过开发人员工具)并将 @Html.DropDownListFor 包装在一个带有 id 的 div 中(例如 #my-selector)。为 div 的子元素设置样式,例如:#my-selector > select { ...正常的 bootstrap form-control 样式}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接