2009-04-23 101 views
121

我在控制器创建一个选择列表的,在视图中显示。我怎样才能让这个ASP.NET MVC SelectList工作?

我试图动态创建它,八九不离十的事..这样的...

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

它编译,但输出是坏...

<select id="PageOptionsDropDown" name="PageOptionsDropDown"> 
    <option>10</option> 
    <option>15</option> 
    <option>25</option> 
    <option>50</option> 
    <option>100</option> 
    <option>1000</option> 
</select> 

注意如何选择项目?

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

+1

六答案......一个收藏...没有upvotes:/我会给它一个+1 – womp 2009-06-26 17:29:18

+0

可能的重复[如何添加项目到ASP.net MVC的SelectList](http://stackoverflow.com/questions/668589/how-can-i -add-an-item-to-a-selectlist-in-asp-net-mvc) – 2015-05-12 14:22:18

回答

122

这是我要做的事

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

在第二眼我不知道我知道你是什么后...

+2

谢谢你帮我把这些东西搞清楚了。 – Cadoo 2009-06-26 17:13:23

+6

不修复所选项目问题,但它是避免选择列表的魔术字符串的好方法!欢呼 – 2009-07-28 19:45:19

+9

要修复所选项目问题,请添加以下代码:`SelectList sList = new SelectList(selectList,“Text”,“Value”,selected);`where'selected`是当前选定的客户 – jao 2012-02-07 10:49:25

45

使用接受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"); 

然后在您的视图:

<%=Html.DropDownList("myList") %> 
+3

漂亮的家伙:)我喜欢!我试图做到这一点..但我无法得到.Select(..)的一部分..不错:)我会在家里尝试它,以后:) – 2009-04-24 01:06:21

+1

Heya Cagdas。效果很好,除非所选字段未被选中。任何想法?这是MVC中的一个错误吗? – 2009-04-25 00:37:57

0

这可能是因为你有你的ViewData的一些模棱两可的情况:

看一下Here

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(), 
                " - "); 

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; 
    } 
} 
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" }, 
} 
1

使用你的例子这个工作对我来说:

控制器:

ViewData["PageOptionsDropDown"] = new SelectList(new[] { "10", "15", "25", "50", "100", "1000" }, "15"); 

观点:

<%= Html.DropDownList("PageOptionsDropDown")%> 
1

我只是跑它像这样,也没有问题,

public class myViewDataObj 
    { 
     public SelectList PageOptionsDropDown { get; set; } 
    } 

public ActionResult About() 
     { 
      myViewDataObj myViewData = new myViewDataObj(); 
      myViewData.PageOptionsDropDown = 
        new SelectList(new[] { "10", "15", "25", "50", "100", "1000" }, "15"); 

      ViewData["myList"] = myViewData.PageOptionsDropDown; 
      return View(); 
     } 

<%=Html.DropDownList("myList") %> 

,如果你做到这一点也工作,

public ActionResult About() 
     { 
      myViewDataObj myViewData = new myViewDataObj(); 
      myViewData.PageOptionsDropDown = 
        new SelectList(new[] { "10", "15", "25", "50", "100", "1000" }); 

      ViewData["myListValues"] = myViewData.PageOptionsDropDown; 
      ViewData["myList"] = "15"; 
      return View(); 
     } 

<%=Html.DropDownList("myList",(IEnumerable<SelectListItem>)ViewData["myListValues"]) %> 
4

看来,如果你有一个强类型的视图,你需要改变下拉的ID,使其不是继承类的属性的名称。然后,您需要在编辑(POST)方法中添加一些逻辑,以便在提交更改之前将选定的值从FORMCollection中提取出来并放入实例中。

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

因此,如果您的课程有一个名为CountryId的字段,并且您显示的是国家/地区名称列表,请使下拉列表中的国家/地区名称代替CountryId,然后在该信息中,您可以使用Collection [ “国家的名字”]。

12

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

您必须将SelectList ctor与SelectListItem [],文本名称,值名称和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"); 

(未测试这一点,但我有同样的问题)

则第二选项将得到所选=“选择”属性。 这看起来像好老的DataSet ;-)

1
MonthRepository monthRepository = new MonthRepository(); 
IQueryable<MonthEntity> entities = monthRepository.GetAllMonth(); 
List<MonthEntity> monthEntities = new List<MonthEntity>(); 

foreach(var r in entities) 
{ 
    monthEntities.Add(r); 
} 

ViewData["Month"] = new SelectList(monthEntities, "MonthID", "Month", "Mars"); 
0

模型选择的值取而不是默认的项目优势。 (我同意我没看过的所有帖子)

0

我不记得如何MVC 1是设置,但它似乎想命名一样,它也属于该领域的选择列表...

我发现,就像上面说的那样,我的选择列表在mvc2中不起作用,当它们发送的ViewData被命名为与字段相同时。

例如:

<%= Html.DropDownListFor((model => model.ForID), (SelectList)ViewData["ForName"]) %>

作品时

<%= Html.DropDownListFor((model => model.ForID), (SelectList)ViewData["ForID"]) %>

不起作用作为ViewData的名字 “FORID” 命名一样,它正在为

领域
1

我这样做:

List<SelectListItem> list = new List<SelectListItem>{ 
new SelectListItem {Selected = true, Text = "Select", Value = "0"}, 
new SelectListItem {Selected = true, Text = "1", Value = "1"}, 
new SelectListItem {Selected = true, Text = "2", Value = "2"} 
}; 
return list.ToArray(); 

ToArray()处理这些问题。

0

可能的解释是您绑定的selectlist值不是字符串。

那么在那个例子中,参数'PageOptionsDropDown'是你模型中的一个字符串吗?因为如果不是,则列表中的选定值将不会显示。

0

如果您在Html.DropDownList扩展方法中查看MVC 2的源代码,它从不检查SelectList类SelectedValue属性。它只会尝试匹配你的模型。

以上所有内容都是关于主题的所有变体,即,如何将一串数据发送到视图以获得下拉列表&它们彼此都很好(或多或少) 。

问题是在视图中。您可以创建自己的DropDownList扩展方法,该方法可以尊重您设置的选择值,也可以手动迭代。哪个最适合你。

10

如果这是字面上所有你想要做的然后就声明数组作为字符串修复所选项目的问题:

myViewData.PageOptionsDropDown = 
    new SelectList(new string[] {"10", "15", "25", "50", "100", "1000"}, "15"); 
2

所有这些问题的答案很好看,但似乎是控制器的准备数据以着名的结构化格式查看vs.让视图简单地迭代通过模型交付的IEnumerable>构建标准选择列表,然后让DefaultModelBinder通过操作参数将选定项传回给您。是的,不,为什么不呢?分离顾虑,是吗?看起来很奇怪,让控制器构建UI和View特定的东西。

18

建设关托马斯·斯托克的回答,我创建了这些重载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()) 
      }; 
     } 
    } 
} 

在你的控制器,你可以做到以下几点:

var pageOptions = new[] { "10", "15", "25", "50", "100", "1000" }; 
ViewBag.PageOptions = pageOptions.ToSelectList(o => o, "15" /*selectedValue*/); 
在您查看

最后,提出:

@Html.DropDownList("PageOptionsDropDown", ViewBag.PageOptions as IEnumerable<SelectListItem>, "(Select one)") 

它会导致所需的输出 - 当然,你可以已经走出"(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> 

更新:修改后的代码清单可以found here与XML注释。

2

简单:

string[] someName = new string[] {"10", "15", "25", "50", "100", "1000"}; 
myViewData.PageOptionsDropDown = new SelectList(someName, "15"); 
4

我有完全相同的问题。解决方案很简单。只需将传递给DropDownList助手的“name”参数更改为与ViewModel中存在的任何属性都不匹配的内容即可。 在这里阅读更多: http://www.dotnetguy.co.uk/post/2009/06/25/net-mvc-selectlists-selected-value-does-not-get-set-in-the-view

我引用了丹华生:

在MVC中,如果认为是强类型的选择列表的所选择的选项将被覆盖和所选择的选项属性在构造函数中设置将永远达不到视图和下拉菜单中的第一个选项将被选中(为什么仍然有点神秘)。

干杯!

0

如果你在你的模型集合,您的看法是强类型,这一些变化将工作:

@Html.DropDownListFor(x => x.RegionID, 
    new SelectList(Model.Regions,"RegionID", "RegionName", Model.RegionID)) 

- 或 -

@Html.DropDownList("RegionID", 
    new SelectList(Model.Regions, "RegionID", "RegionName", Model.RegionID)) 
6

这很简单,拿到的SelectList和SelectedValue一起工作,即使你的属性不是像Int,String或Double值这样的简单对象。

例子:

假设我区对象是这样的:

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

而且你的视图模型是一样的东西:

public class ContactViewModel { 
    public DateTime Date { get; set; } 
    public Region Region { get; set; } 
    public List<Region> Regions { get; set; } 
} 

你可以有下面的代码:

@Html.DropDownListFor(x => x.Region, new SelectList(Model.Regions, "ID", "Name")) 

只有当你越级区对象的ToString方法将是这样的:

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

    public override string ToString() 
    { 
     return ID.ToString(); 
    } 
} 

这有100%的garantee工作。

但我真的相信SelectList 100%在所有的环境中工作的最好方法是通过使用Equals方法来测试项目集合中每个项目的DropDownList或ListBox属性值。

1

如果你想要一些随机的文字传递给你的DropDownList,例如- 选择 -你可以很容易做到这一点使用此代码:

@Html.DropDownListFor(x => x.CategoryId, new SelectList(Model.Categories, "Id", "Name"), "--Select--", new { @class = "form-control" }) 
相关问题