2011-02-17 125 views
1

我从一个枚举中创建了一个SelectList。枚举有一个描述,并且将int值设置为我想要存储在数据库中的值。为什么我的下拉列表默认为给定值?

问题是,我在施工上设置的默认(BLANK)没有被使用。

这是我的枚举:

public enum Stage 
{ 
    [Description("")] 
    BLANK = -99, 
    [Description("No Data")] 
    NoData = 9999, 
    [Description("Nil")] 
    Nil = 0, 
    [Description("Action")] 
    SAction = 1, 
    [Description("Action Plus")] 
    SActionPlus = 2, 
    [Description("Full")] 
    Full = 3 
} 

我在我的控制器创建它:

private static IEnumerable<SelectListItem> GenerateSenStageList() 
{ 
    var values = from Stage e in Enum.GetValues(typeof(Stage)) 
       select new { ID = (int)e, Name = e.ToDescription() }; 

    return new SelectList(values, "Id", "Name", (int)Stage.BLANK); 
} 

如果我想设置所选项目的最后一个参数。 我将其指定为ViewData的,和访问它像:

<%= Html.DropDownList("Stage", (IEnumerable<SelectListItem>)ViewData["StageList"])%> 

然而,无总是选择值。

我在这里错过了什么?

谢谢!

回答

1

Iainie,

使用你的代码,我设法得到这个工作的第一次。这里的(使用测试的AccountController)我修改的代码[使用.NET 3.5]:

// from account controller - put the enum, etc in there for brevity 
public enum Stage 
{ 
    [Description("")] 
    BLANK = -99, 
    [Description("No Data")] 
    NoData = 9999, 
    [Description("Nil")] 
    Nil = 0, 
    [Description("Action")] 
    SAction = 1, 
    [Description("Action Plus")] 
    SActionPlus = 2, 
    [Description("Full")] 
    Full = 3 
} 

public static IEnumerable<SelectListItem> GenerateSenStageList() 
{ 
    var values = from Stage e in Enum.GetValues(typeof(Stage)) 
       select new { ID = (int)e, Name = e.ToDescription() }; 

    var sellist= new SelectList(values, "Id", "Name", (int)Stage.BLANK); 
    return sellist; 
} 

public virtual ActionResult LogOn() 
{ 
    var res = GenerateSenStageList(); 
    ViewData["StageList"] = res; 
    return View(); 
} 

// the ToDescription() extension method 
public static class Extn 
{ 
    public static string ToDescription(this Enum value) 
    { 
     FieldInfo fi = value.GetType().GetField(value.ToString()); 

     var attributes = 
      (DescriptionAttribute[])fi.GetCustomAttributes(
      typeof(DescriptionAttribute), 
      false); 

     if (attributes != null && 
      attributes.Length > 0) 
      return attributes[0].Description; 
     else 
      return value.ToString(); 
    } 
} 

// then in the LogOn view: 
<%= Html.DropDownList("Stage", (IEnumerable<SelectListItem>)ViewData["StageList"])%> 

这一切工作完全按照你希望的,所以我不知道如果从视图中的调用被莫名其妙地越来越有点欺骗。试试我上面的例子,看看在选择列表生成的代码是否有任何细微的差异等。

2

最后一个参数确定所选值。但是,您要传递一个Stage枚举值作为最后一个参数,而列表的实际元素由一个ID值构成一个Stage值。要做到这一点,您必须将values中的实际对象传递给阶段值BLANK。

+0

如果这是真的,那么我很惊讶。我认为int的值(在这种情况下ID)类型将正确匹配选定的值也是int。有趣。 – Tx3 2011-02-17 08:48:41

+0

但是选定的值不是int类型的。这是一个匿名类型包含一个int和一个阶段 – 2011-02-17 08:58:35

1

只是一个猜测,但:

你投了ViewData["StageList"]IEnumerable<SelectListItem>。该枚举可能是您在控制器中创建的SelectList,但它没有SelectedValue属性。

也许它适用,如果你将ViewData["StageList"]改为SelectList而不是?

<%= Html.DropDownList("Stage", (SelectList)ViewData["StageList"])%> 

在这种情况下使用的界面可能是错误的事情,因为你实际上需要由SelectList对象提供的信息。

+0

感谢您的答案 - 我已经改变它,但没有喜悦... – laura 2011-02-17 09:51:18

0

@Ken Wayne VanderLinde是正确的。如果你使用C#4.0,那么你可以这样做来填充选定的值:

private static IEnumerable<SelectListItem> GenerateSenStageList() 
{ 
    var values = from Stage e in Enum.GetValues(typeof(Stage)) 
     select new { ID = (int)e, Name = e.ToDescription() }; 
    return new SelectList(values, "Id", "Name", values.Cast<dynamic>().Where(x => (x.ID == (int)Stage.BLANK))); 
}