如何让这个ASP.NET MVC SelectList工作?

Pur*_*ome 125 c# asp.net-mvc selectlist

我在控制器中创建一个selectList,以在视图中显示.

我正试图在飞行中创建它,有点像......这样......

myViewData.PageOptionsDropDown = 
   new SelectList(new [] {"10", "15", "25", "50", "100", "1000"}, "15");
Run Code Online (Sandbox Code Playgroud)

它编译,但输出不好......

<select id="PageOptionsDropDown" name="PageOptionsDropDown">
    <option>10</option>
    <option>15</option>
    <option>25</option>
    <option>50</option>
    <option>100</option>
    <option>1000</option>
</select>
Run Code Online (Sandbox Code Playgroud)

注意没有选择项目?

我怎样才能解决这个问题??

mhe*_*xon 127

我就是这样做的

IList<Customer> customers = repository.GetAll<Customer>();
IEnumerable<SelectListItem> selectList = 
    from c in customers
    select new SelectListItem
    {
        Selected = (c.CustomerID == invoice.CustomerID),
        Text = c.Name,
        Value = c.CustomerID.ToString()
    };
Run Code Online (Sandbox Code Playgroud)

乍一看,我不确定我知道你在追求什么......

  • 要修复所选项目问题,请添加以下代码:`SelectList sList = new SelectList(selectList,"Text","Value",selected);`where`selected`是当前选定的客户 (10认同)
  • 不修复所选项目问题,但它是避免选择列表的魔术字符串的好方法!干杯 (6认同)
  • 谢谢你,这帮我搞清楚这些东西. (2认同)

Tho*_*ock 68

我使用扩展方法:

用法

var departmentItems = departments.ToSelectList(d => d.Code + 
                                               " - " + d.Description,
                                               d => d.Id.ToString(),
                                               " - ");

var functionItems = customerFunctions.ToSelectList(f => f.Description, 
                                                   f => f.Id.ToString(), 
                                                   " - ");
Run Code Online (Sandbox Code Playgroud)

public static class MCVExtentions
{
    public static List<SelectListItem> ToSelectList<T>(
        this IEnumerable<T> enumerable, 
        Func<T, string> text, 
        Func<T, string> value, 
        string defaultOption)
    {
        var items = enumerable.Select(f => new SelectListItem()
                                     {
                                         Text = text(f), 
                                         Value = value(f) 
                                     }).ToList();
        items.Insert(0, new SelectListItem()
                    {
                        Text = defaultOption, 
                        Value = "-1" 
                    });
        return items;
    }
}
Run Code Online (Sandbox Code Playgroud)


Çağ*_*kin 48

使用接受items, dataValueField, dataTextField, selectedValue作为参数的构造函数:

ViewData["myList"] = 
                new SelectList(new[] { "10", "15", "25", "50", "100", "1000" }
                .Select(x => new {value = x, text = x}), 
                "value", "text", "15");
Run Code Online (Sandbox Code Playgroud)

然后在你看来:

<%=Html.DropDownList("myList") %>
Run Code Online (Sandbox Code Playgroud)

  • 好伙计:)我喜欢!我试图这样做..但我无法得到.Select(..)部分..很好:)我会在家里尝试,后来:) (3认同)
  • 将SelectList项添加到ViewData对象时(如在ViewData ["myList"] = new SelectList ..中),然后使用<%= Html.DropDownList("myList")%>渲染它时,所选项目有效.虽然不这样做但我无法让所选项目工作.奇怪的. (2认同)

Jus*_*lle 18

建立Thomas Stock的答案,我创建了这些重载ToSelectList方法:

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

public static partial class Helpers
{
    public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, object> value, bool selectAll = false)
    {
        return enumerable.ToSelectList(value, value, selectAll);
    }

    public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, object> value, object selectedValue)
    {
        return enumerable.ToSelectList(value, value, new List<object>() { selectedValue });
    }

    public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, object> value, IEnumerable<object> selectedValues)
    {
        return enumerable.ToSelectList(value, value, selectedValues);
    }

    public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, object> value, Func<T, object> text, bool selectAll = false)
    {
        foreach (var f in enumerable.Where(x => x != null))
        {
            yield return new SelectListItem()
            {
                Value = value(f).ToString(),
                Text = text(f).ToString(),
                Selected = selectAll
            };
        }
    }

    public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, object> value, Func<T, object> text, object selectedValue)
    {
        return enumerable.ToSelectList(value, text, new List<object>() { selectedValue });
    }

    public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, object> value, Func<T, object> text, IEnumerable<object> selectedValues)
    {
        var sel = selectedValues != null
            ? selectedValues.Where(x => x != null).ToList().ConvertAll<string>(x => x.ToString())
            : new List<string>();

        foreach (var f in enumerable.Where(x => x != null))
        {
            yield return new SelectListItem()
            {
                Value = value(f).ToString(),
                Text = text(f).ToString(),
                Selected = sel.Contains(value(f).ToString())
            };
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在控制器中,您可以执行以下操作:

var pageOptions = new[] { "10", "15", "25", "50", "100", "1000" };
ViewBag.PageOptions = pageOptions.ToSelectList(o => o, "15" /*selectedValue*/);
Run Code Online (Sandbox Code Playgroud)

最后在你的视图中,放置:

@Html.DropDownList("PageOptionsDropDown", ViewBag.PageOptions as IEnumerable<SelectListItem>, "(Select one)")
Run Code Online (Sandbox Code Playgroud)

它会产生所需的输出 - 当然,"(Select one)"如果你不想要第一个空项,你可以省略上面的optionLabel:

<select id="PageOptionsDropDown" name="PageOptionsDropDown">
<option value="">(Select one)</option>
<option value="10">10</option>
<option selected="selected" value="15">15</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
<option value="1000">1000</option>
</select>
Run Code Online (Sandbox Code Playgroud)

更新:修改后的代码清单可以在此处找到 XML注释.


小智 13

问题是,SelectList按设计工作.错误在设计中.您可以在SelectedItem中设置Selected Property,但如果您使用GetEnumerator()遍历列表(或者如果Mvc为您执行此操作),则将完全忽略此属性.Mvc将创建新的SelectListItems.

您必须将SelectList ctor与SelectListItem [],Text-Name,Value-Name和SelectedValue一起使用.请注意将SelectValue传递给您想要选择的SelectListItem的VALUE,而不是SelectListItem本身!例:

SelectList sl = new SelectList( new[]{
  new SelectListItem{ Text="one", Value="1"},
  new SelectListItem{ Text="two", Value="2"},
  new SelectListItem{ Text="three", Value="3"}
}, "Text", "Value", "2" );
Run Code Online (Sandbox Code Playgroud)

(没有测试过,但我有同样的问题)

然后第二个选项将获得selected ="selected"属性.这看起来像旧的DataSet ;-)


mur*_*rki 11

这是一个选项:

myViewData.PageOptionsDropDown = new[] 
{
 new SelectListItem { Text = "10", Value = "10" },
 new SelectListItem { Text = "15", Value = "15", Selected = true }
 new SelectListItem { Text = "25", Value = "25" },
 new SelectListItem { Text = "50", Value = "50" },
 new SelectListItem { Text = "100", Value = "100" },
 new SelectListItem { Text = "1000", Value = "1000" },
}
Run Code Online (Sandbox Code Playgroud)


Mat*_*ton 10

如果这就是您想要做的所有事情,那么只需将数组声明为字符串即可修复所选项目问题:

myViewData.PageOptionsDropDown = 
   new SelectList(new string[] {"10", "15", "25", "50", "100", "1000"}, "15");
Run Code Online (Sandbox Code Playgroud)


ara*_*rog 7

使SelectList和SelectedValue一起工作非常简单,即使您的属性不是像Int,String或Double值这样的简单对象.

例:

假设我们的Region对象是这样的:

public class Region {
     public Guid ID { get; set; }
     public Guid Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

你的视图模型是这样的:

public class ContactViewModel {
     public DateTime Date { get; set; }
     public Region Region { get; set; }
     public List<Region> Regions { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

您可以拥有以下代码:

@Html.DropDownListFor(x => x.Region, new SelectList(Model.Regions, "ID", "Name")) 
Run Code Online (Sandbox Code Playgroud)

仅当您将Region对象的ToString方法重写为以下内容时:

public class Region {
     public Guid ID { get; set; }
     public Guid Name { get; set; }

     public override string ToString()
     {
         return ID.ToString();
     }
}
Run Code Online (Sandbox Code Playgroud)

这是100%保证工作.

但我真的相信让AllList 100%在所有环境中工作的最佳方法是使用Equals方法针对items集合上的每个项目测试DropDownList或ListBox属性值.


小智 5

看来如果你有一个强类型视图,你需要更改下拉列表的ID,这样它就不是继承类中属性的名称.然后,您需要在编辑(POST)方法中放置一些逻辑,以从FORMCollection中提取所选值,并在提交更改之前将其放到您的实例上.

这当然有点奇怪,但我尝试了它,它的工作原理.

因此,如果您的类有一个名为CountryId的字段,并且您正在显示国家/地区名称列表,请将该下拉列表的ID设置为CountryName而不是CountryId,然后在帖子中,您可以使用Collection ["CountryName"]执行某些操作.