MVC 中的 Optgroup 下拉支持 - 模型绑定问题

发布于 2024-10-01 12:00:55 字数 4531 浏览 1 评论 0原文

我想知道是否有人可以阐明这个问题。

我有一个选项组下拉菜单用于选择一个人的种族 - 但它没有将值存储在模型中。

ViewModel

    [UIHint("EthnicOriginEditorTemplate")]
    [DisplayName("Question 6: Ethnic Origin")]
    public int EthnicOrigin { get; set; }

Helper:GroupDropList.Cs

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;

namespace Public.Helpers
{
    public static class GroupDropListExtensions
    {
        public static string GroupDropList(this HtmlHelper helper, string name, IEnumerable<GroupDropListItem> data, int SelectedValue, object htmlAttributes)
        {
            if (data == null && helper.ViewData != null)
                data = helper.ViewData.Eval(name) as IEnumerable<GroupDropListItem>;
            if (data == null) return string.Empty;

            var select = new TagBuilder("select");

            if (htmlAttributes != null)
                select.MergeAttributes(new RouteValueDictionary(htmlAttributes));

            select.GenerateId(name);

            var optgroupHtml = new StringBuilder();
            var groups = data.ToList();
            foreach (var group in data)
            {
                var groupTag = new TagBuilder("optgroup");
                groupTag.Attributes.Add("label", helper.Encode(group.Name));
                var optHtml = new StringBuilder();
                foreach (var item in group.Items)
                {
                    var option = new TagBuilder("option");
                    option.Attributes.Add("value", helper.Encode(item.Value));
                    if (SelectedValue != 0 && item.Value == SelectedValue)
                        option.Attributes.Add("selected", "selected");
                    option.InnerHtml = helper.Encode(item.Text);
                    optHtml.AppendLine(option.ToString(TagRenderMode.Normal));
                }
                groupTag.InnerHtml = optHtml.ToString();
                optgroupHtml.AppendLine(groupTag.ToString(TagRenderMode.Normal));
            }
            select.InnerHtml = optgroupHtml.ToString();
            return select.ToString(TagRenderMode.Normal);
        }
    }

    public class GroupDropListItem
    {
        public string Name { get; set; }
        public List<OptionItem> Items { get; set; }
    }

    public class OptionItem
    {
        public string Text { get; set; }
        public int Value { get; set; }
    }
}

这是我的 EditorTemplate

<%@ Import Namespace="Public.Helpers"%>
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<int>"%>

<%=Html.GroupDropList("EthnicOrigin",
                                 new[]
                                    {                                        
                                        new GroupDropListItem
                                             {
                                                 Name = "Ethnicity",
                                                 Items = new List<OptionItem>
                                                         {
                                                             new OptionItem {Value = 0, Text = "Please Select"}
                                                         }
                                             },

                                        new GroupDropListItem
                                             {
                                                 Name = "a) White",
                                                 Items = new List<OptionItem>
                                                         {
                                                             new OptionItem {Value = 1, Text = "British"},
                                                             new OptionItem {Value = 2, Text = "Irish"},
                                                             new OptionItem {Value = 3, Text = "Other White (Please specify below)"}
                                                         }
                                             },

                                         --snip

                                     }, Model, null)%>

在视图中我将其引用为:

<%=Html.EditorFor(x => x.EthnicOrigin, "EthnicOriginEditorTemplate")%>

但是它没有将选定的值传递到模型中...有没有人遇到过类似的问题...提前非常感谢您的一些指点。

I wonder if anyone can shed some light on this problem..

I've got an option group drop-down for selecting a person's ethnicity – however it’s not storing the value in the model.

ViewModel

    [UIHint("EthnicOriginEditorTemplate")]
    [DisplayName("Question 6: Ethnic Origin")]
    public int EthnicOrigin { get; set; }

Helper : GroupDropList.Cs

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;

namespace Public.Helpers
{
    public static class GroupDropListExtensions
    {
        public static string GroupDropList(this HtmlHelper helper, string name, IEnumerable<GroupDropListItem> data, int SelectedValue, object htmlAttributes)
        {
            if (data == null && helper.ViewData != null)
                data = helper.ViewData.Eval(name) as IEnumerable<GroupDropListItem>;
            if (data == null) return string.Empty;

            var select = new TagBuilder("select");

            if (htmlAttributes != null)
                select.MergeAttributes(new RouteValueDictionary(htmlAttributes));

            select.GenerateId(name);

            var optgroupHtml = new StringBuilder();
            var groups = data.ToList();
            foreach (var group in data)
            {
                var groupTag = new TagBuilder("optgroup");
                groupTag.Attributes.Add("label", helper.Encode(group.Name));
                var optHtml = new StringBuilder();
                foreach (var item in group.Items)
                {
                    var option = new TagBuilder("option");
                    option.Attributes.Add("value", helper.Encode(item.Value));
                    if (SelectedValue != 0 && item.Value == SelectedValue)
                        option.Attributes.Add("selected", "selected");
                    option.InnerHtml = helper.Encode(item.Text);
                    optHtml.AppendLine(option.ToString(TagRenderMode.Normal));
                }
                groupTag.InnerHtml = optHtml.ToString();
                optgroupHtml.AppendLine(groupTag.ToString(TagRenderMode.Normal));
            }
            select.InnerHtml = optgroupHtml.ToString();
            return select.ToString(TagRenderMode.Normal);
        }
    }

    public class GroupDropListItem
    {
        public string Name { get; set; }
        public List<OptionItem> Items { get; set; }
    }

    public class OptionItem
    {
        public string Text { get; set; }
        public int Value { get; set; }
    }
}

This is my EditorTemplate

<%@ Import Namespace="Public.Helpers"%>
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<int>"%>

<%=Html.GroupDropList("EthnicOrigin",
                                 new[]
                                    {                                        
                                        new GroupDropListItem
                                             {
                                                 Name = "Ethnicity",
                                                 Items = new List<OptionItem>
                                                         {
                                                             new OptionItem {Value = 0, Text = "Please Select"}
                                                         }
                                             },

                                        new GroupDropListItem
                                             {
                                                 Name = "a) White",
                                                 Items = new List<OptionItem>
                                                         {
                                                             new OptionItem {Value = 1, Text = "British"},
                                                             new OptionItem {Value = 2, Text = "Irish"},
                                                             new OptionItem {Value = 3, Text = "Other White (Please specify below)"}
                                                         }
                                             },

                                         --snip

                                     }, Model, null)%>

And in the view I'm referencing it as:

<%=Html.EditorFor(x => x.EthnicOrigin, "EthnicOriginEditorTemplate")%>

However it's not passing through the selected Value into the model... has anyone experienced similar problems... many thanks in advance for some pointers.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

临走之时 2024-10-08 12:00:55

您的 select 没有 name 属性,因此当您提交表单时,所选值不会发送到服务器。您需要添加一个名称:

select.GenerateId(name);
select.MergeAttribute("name", name);

Your select doesn't have a name attribute and so when you submit the form the selected value is not sent to the server. You need to add a name:

select.GenerateId(name);
select.MergeAttribute("name", name);
稚然 2024-10-08 12:00:55

只是更改了帮助程序类,使其适用于 MVC 3 并具有 nullable int。
非常感谢您的课程,节省了我很多时间。

public static class GroupDropListExtensions
{
    public static MvcHtmlString GroupDropList(this HtmlHelper helper, string name, IEnumerable<GroupDropListItem> data, int? SelectedValue, object htmlAttributes)
    {
        if (data == null && helper.ViewData != null)
            data = helper.ViewData.Eval(name) as IEnumerable<GroupDropListItem>;
        if (data == null) return new MvcHtmlString(string.Empty);

        var select = new TagBuilder("select");

        if (htmlAttributes != null)
            select.MergeAttributes(new RouteValueDictionary(htmlAttributes));

        select.GenerateId(name);
        select.MergeAttribute("name", name);

        var optgroupHtml = new StringBuilder();
        var groups = data.ToList();
        foreach (var group in data)
        {
            var groupTag = new TagBuilder("optgroup");
            groupTag.Attributes.Add("label", helper.Encode(group.Name));
            var optHtml = new StringBuilder();
            foreach (var item in group.Items)
            {
                var option = new TagBuilder("option");
                option.Attributes.Add("value", helper.Encode(item.Value));
                if (SelectedValue != 0 && item.Value == SelectedValue)
                    option.Attributes.Add("selected", "selected");
                option.InnerHtml = helper.Encode(item.Text);
                optHtml.AppendLine(option.ToString(TagRenderMode.Normal));
            }
            groupTag.InnerHtml = optHtml.ToString();
            optgroupHtml.AppendLine(groupTag.ToString(TagRenderMode.Normal));
        }
        select.InnerHtml = optgroupHtml.ToString();
        return new MvcHtmlString(select.ToString(TagRenderMode.Normal));
    }
}

public class GroupDropListItem
{
    public string Name { get; set; }
    public List<OptionItem> Items { get; set; }
}

public class OptionItem
{
    public string Text { get; set; }
    public int Value { get; set; }
}

Just changed the helper class to get it work for MVC 3 and with nullable int.
Thanks a lot for the class, saves me plenty of time.

public static class GroupDropListExtensions
{
    public static MvcHtmlString GroupDropList(this HtmlHelper helper, string name, IEnumerable<GroupDropListItem> data, int? SelectedValue, object htmlAttributes)
    {
        if (data == null && helper.ViewData != null)
            data = helper.ViewData.Eval(name) as IEnumerable<GroupDropListItem>;
        if (data == null) return new MvcHtmlString(string.Empty);

        var select = new TagBuilder("select");

        if (htmlAttributes != null)
            select.MergeAttributes(new RouteValueDictionary(htmlAttributes));

        select.GenerateId(name);
        select.MergeAttribute("name", name);

        var optgroupHtml = new StringBuilder();
        var groups = data.ToList();
        foreach (var group in data)
        {
            var groupTag = new TagBuilder("optgroup");
            groupTag.Attributes.Add("label", helper.Encode(group.Name));
            var optHtml = new StringBuilder();
            foreach (var item in group.Items)
            {
                var option = new TagBuilder("option");
                option.Attributes.Add("value", helper.Encode(item.Value));
                if (SelectedValue != 0 && item.Value == SelectedValue)
                    option.Attributes.Add("selected", "selected");
                option.InnerHtml = helper.Encode(item.Text);
                optHtml.AppendLine(option.ToString(TagRenderMode.Normal));
            }
            groupTag.InnerHtml = optHtml.ToString();
            optgroupHtml.AppendLine(groupTag.ToString(TagRenderMode.Normal));
        }
        select.InnerHtml = optgroupHtml.ToString();
        return new MvcHtmlString(select.ToString(TagRenderMode.Normal));
    }
}

public class GroupDropListItem
{
    public string Name { get; set; }
    public List<OptionItem> Items { get; set; }
}

public class OptionItem
{
    public string Text { get; set; }
    public int Value { get; set; }
}
猫弦 2024-10-08 12:00:55

从 ASP.NET MVC 5.2 开始,使用 SelectListGroup 原生支持此功能:

var items = new List<SelectListItem>(); 
var group1 = new SelectListGroup() { Name = "Group 1" };
items.Add(new SelectListItem() { Text = "Item1", Group = group1 }); 

然后在 MVC 中,执行以下操作:

@Html.DropDownList("select", items) 

This is supported natively using SelectListGroup as of ASP.NET MVC 5.2:

var items = new List<SelectListItem>(); 
var group1 = new SelectListGroup() { Name = "Group 1" };
items.Add(new SelectListItem() { Text = "Item1", Group = group1 }); 

Then in MVC, do

@Html.DropDownList("select", items) 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文