2012-03-20 60 views
6

我在选择DropDownList的值时遇到问题。我一直在阅读所有类似的帖子,我无法获得解决方案。SelectListItem中的选定属性无法工作(DropDownListFor)

的实际做法似乎对我非常好,因为我可以检查,这将是选择列表的中的字段:

var selectList = new List<SelectListItem>(
    from variable in someKindOfCollection 
    select new SelectListItem 
     { 
      Selected = variable.Property == selection, 
      Text = variable.Property, 
      Value = variable.Property 
     }); 

据称,这给了我完全控制。在建立selectList之后,我可以用调试器检查变量。一切正常,其中一个标记了“Selected”属性。

然后我用DropDownListFor为了显示对视图:

@Html.DropDownListFor(
    g => g.SomePropertyInModel , selectList, new { @class = "cssClass" }) 

,但它不工作,从来没有......“渲染”下拉列表中,但没有被选中。

感谢很多:)

所有我要道歉的新的例子 第一。我一直在隐藏信息,当然是完全无意的。 所有的代码发生在一个剃刀循环内:

@foreach (var loopVariable in Model.Collection) 
{ 
    if (Model.SomeCondition != null) 
    { 
     selection = someValue; 
    } 

    var selectList = new List<SelectListItem>(
     from variable in someKindOfCollection 
     select new SelectListItem 
    { 
     Selected = variable.Property == selection, 
     Text = variable.Property, 
     Value = variable.Property 
    }); 

    @Html.DropDownListFor(
     g => g.SomePropertyInModel , selectList, new { @class = "cssClass" }) 

} 

所以,这是选择列表的的事实,导致出现该问题的局部变量?对不起,我没有想到它是。

+1

您可以包含下拉菜单的HTML输出吗? – Brandon 2012-03-20 18:24:32

+0

感谢布兰登,我已更新帖子。 – IoChaos 2012-03-21 14:06:33

回答

2

我推荐一个视图模型的使用:

public ActionResult Index() 
{ 
    var model = new MyViewModel 
    { 
     // this will preselect the item with value = "2.400 €" in the collection 
     SelectedValue = "2.400 €", 

     Values = someKindOfCollection 
    }; 
    return View(model); 
} 

,并在视图:

@Html.DropDownListFor(
    g => g.SelectedValue, 
    new SelectList(Model.Values, "SomePropertyForValue", "SomePropertyForText"), 
    new { @class = "cssClass" } 
) 
+0

嗨达林,谢谢你的时间。我不明白你的例子与我的不同。我看到你正在使用一个SelectList(我没有使用任何运气)。我的收藏和选定的字段也来自viewModel。 – IoChaos 2012-03-21 14:06:14

+0

@IoChaos,我不知道。你可以告诉我它有什么不同。因为我的工作。我已经测试过它。 – 2012-03-21 14:30:27

+0

对不起Darin :(请......看看我最后一次更新 – IoChaos 2012-03-21 14:41:13

2

你应该重新调试你的选择列表中。

您的任何选项值都没有selected=selected

尝试硬编码的列表,像

SelectList = new List<SelectListItem> 
     { 
      new SelectListItem{Text = "600 €", Value="600 €" , Selected = false}, 
      new SelectListItem{Text = "1.200 €", Value="1.200 €" , Selected = false}, 
      new SelectListItem{Text = "2.400 €", Value="2.400 €" , Selected = false}, 
      new SelectListItem{Text = "3.000 €", Value="3.000 €" , Selected = true}, 
     }; 

使用此代码,你的Html.DropDownFor选择列表的正常工作,并生成该HTML

<select id="TheID" name="TheName" class="cssClass"> 
    <option value="600 €">600 €</option> 
    <option value="1.200 €">1.200 €</option> 
    <option value="2.400 €">2.400 €</option> 
    <option value="3.000 €" selected="selected">3.000 €</option> 
</select> 

从你的代码,我不能告诉如果您的比较是将其中一个Selected属性设置为true,但这可能是您的代码无法工作的原因。

+0

Thanks Brandon。我已经硬编码了集合,它没有工作,但我发现了一些东西。当我生成集合时,其中一个项目是Selected = true。在包含“DropDownListFor”的行之后,所有属性都是false 。这是正常的吗? – IoChaos 2012-03-21 14:29:25

+1

@IoChaos,不是我所知道的,也许它可以帮助你发布整个可重现的例子,你说你从ViewMod el,但是从你的'selectList'声明看起来你正在声明一个局部变量。也许我们需要看看你使用的所有代码,因为Darin和我发布的代码都应该可以工作。 – Brandon 2012-03-21 14:32:55

+0

对不起布兰登:(......请看我上次更新 – IoChaos 2012-03-21 14:41:00

4

我认为你遇到了同样的问题。我查看了源代码以找到我的解决方案,看起来这对我来说是一个bug。下面的DropDownListFor应该有所帮助,关键是你将选定的值传递给html助手。希望这可以帮助。

public static class SelectExtensions { 
    public static IHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string selectedValue, string optionLabel, object htmlAttributes = null) { 
     return DropDownListHelper(helper, ExpressionHelper.GetExpressionText(expression), selectList, selectedValue, optionLabel, htmlAttributes); 
    } 

    /// <summary> 
    /// This is almost identical to the one in ASP.NET MVC 3 however it removes the default values stuff so that the Selected property of the SelectListItem class actually works 
    /// </summary> 
    private static IHtmlString DropDownListHelper(HtmlHelper helper, string name, IEnumerable<SelectListItem> selectList, string selectedValue, string optionLabel, object htmlAttributes) { 
     name = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name); 

     // Convert each ListItem to an option tag 
     var listItemBuilder = new StringBuilder(); 

     // Make optionLabel the first item that gets rendered 
     if (optionLabel != null) 
      listItemBuilder.AppendLine(ListItemToOption(new SelectListItem() { Text = optionLabel, Value = String.Empty, Selected = false }, selectedValue)); 

     // Add the other options 
     foreach (var item in selectList) { 
      listItemBuilder.AppendLine(ListItemToOption(item, selectedValue)); 
     } 

     // Now add the select tag 
     var tag = new TagBuilder("select") { InnerHtml = listItemBuilder.ToString() }; 
     tag.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)); 
     tag.MergeAttribute("name", name, true); 
     tag.GenerateId(name); 

     // If there are any errors for a named field, we add the css attribute 
     ModelState modelState; 

     if (helper.ViewData.ModelState.TryGetValue(name, out modelState)) { 
      if (modelState.Errors.Count > 0) 
       tag.AddCssClass(HtmlHelper.ValidationInputCssClassName); 
     } 

     // Add the unobtrusive validation attributes 
     tag.MergeAttributes(helper.GetUnobtrusiveValidationAttributes(name)); 

     return tag.ToHtmlString(TagRenderMode.Normal); 
    } 

    private static string ListItemToOption(SelectListItem item, string selectedValue) { 
     var tag = new TagBuilder("option") { InnerHtml = HttpUtility.HtmlEncode(item.Text) }; 

     if (item.Value != null) 
      tag.Attributes["value"] = item.Value; 

     if ((!string.IsNullOrEmpty(selectedValue) && item.Value == selectedValue) || item.Selected) 
      tag.Attributes["selected"] = "selected"; 

     return tag.ToString(TagRenderMode.Normal); 
    } 
} 
+0

我刚刚更新了这个修补程序,以确保在使用匿名对象时提供HTML 5数据属性。 – nfplee 2013-11-26 13:47:37

1

我有一个类似的问题,原因是我没有设置我的视图模型,由SelectListItems来源属性的值。实际上你根本不需要设置“Selected”属性。要使用原始示例中的措辞,只需将“SomePropertyOnModel”设置为当前所选内容即可。 DropDownListFor将适当地绑定“Selected”属性。

2

我不知道这是否会帮助任何人,但是这解决了这个问题对我来说....

我有收集和在我的模型选择的值两者。

我改变了我的看法来自:

@Html.DropDownListFor(
g => g.CollectionName, 
new SelectList(Model.CollectionName, "SomePropertyForValue", "SomePropertyForText", Model.SelectedValue), 
new { @class = "cssClass" } 
) 

@Html.DropDownListFor(
g => g.SelectedValue, 
new SelectList(Model.CollectionName, "SomePropertyForValue", "SomePropertyForText", Model.SelectedValue), 
new { @class = "cssClass" } 
) 

当我到DropDownListFor第一个参数引用的集合,我会得到下拉列表中,但所选择的价值绝不会坚持。

-1

存在问题,g.SelectedValue必须是模型中的可空类型。

2

这个问题的解决方案是简单的,我们都觉得...

所有我们需要做的,返回时从控制器的视图,设置属性的视图模型中该元素的下拉列表当我们做到这一点

@Html.DropDownListFor(
g => g.SomePropertyInModel , selectList, new { @class = "cssClass" }) 

中的HtmlHelper会自动拿起默认值,显示在DropDownList的

model.SomePropertyInModel =“5”例如

是这样的:即 - 必然

简单!

希望它可以帮助你和所有其他人 - 像我一样! - 已经花了很多时间寻找解决这个明显问题的方法。

0

我对DropDownListFor的建议是,

  • 有被传递到View一个IEnumerable属性模型(或视图模型)。你的情况,例如:

    private IEnumerable<SelectListItem> GetListItems() 
    { 
        var selectList = db.YourDBThings 
         .Where(t => t.IsCool == true) 
         .Select(x => new SelectListItem 
          { 
          Value = x.Id.ToString(), 
          Text = x.Name 
          }); 
        return new SelectList(issues, "Value", "Text"); 
    } 
    
  • ,然后添加这IEnumerable的到你的对象,假设你也有你的对象,有一个项目(将被设置为选择一个)的属性相匹配的一个在“值”列表:

    FancyViewModel myFancyViewModel = new FancyViewModel(); 
    myFancyViewModel.ListOptions = GetListItems(); 
    myFancyViewModel.SelectedThingId = 3; //this 3 would match one of the value in the list 
    //.... 
    return View(myFancyViewModel); 
    
  • 然后在您收到包含的项目列表中FancyViewModel实例的视图:

    @model Project.ViewModels.FancyViewModel 
    @*...*@ 
    @Html.DropDownListFor(x=>x.SelectedThingId, Model.ListOptions) 
    

DropDownListFor中的第一个参数指定包含将在列表中选择的字段的TProperty。第二个是来自该模型的列表本身(尽管它可以从任何地方检索!)

相关问题