【问题标题】:MultiSelectList does not highlight items in the selectedValues listMultiSelectList 不会突出显示 selectedValues 列表中的项目
【发布时间】:2012-06-22 07:41:27
【问题描述】:

在 ASP.NET MVC (Razor) 项目中,我在编辑视图中使用带有多选选项的 ListBox,在 MultiSelectList 中使用 selectedValues 突出显示先前选择的项目时出现问题,所以我之前问过question on SO。根据对该问题给出的答案,我决定使用 ViewModel(带有 AutoMapper)将数据传递给 View,而不使用 ViewBag,但我仍然有同样的问题。它没有选择给出的项目selectedValues 列表

这是我的新代码

模型

public class Post
{
    public int Id { get; set; }
    ...
    public string Tags { get; set; }

}

public class PostEditViewModel
{
    private DocLibraryContext db = new DocLibraryContext();

    public int Id { get; set; }
    ..
    public MultiSelectList TagsList { get; set; }

}

控制器

public ActionResult Edit(int id)
    {

        Post post = db.Posts.Find(id);
        PostEditViewModel postEditViewModel = Mapper.Map<Post, PostEditViewModel>(post);

        var tagsQuery = from d in db.Tags
                        orderby d.Name
                        select d;
        postEditViewModel.TagsList = new MultiSelectList(tagsQuery, "Id", "Name", post.Tags.Split(','));

        return View(postEditViewModel);
    }

查看

<div class="editor-field">
    @Html.ListBoxFor(model => model.Tags, Model.TagsList as MultiSelectList)
</div>

我在这里做错了什么?请帮忙....


更新 1:

将控制器更改为

public ActionResult Edit(int id)
    {

        Post post = db.Posts.Find(id);
        PostEditViewModel postEditViewModel = Mapper.Map<Post, PostEditViewModel>(post);

        var tagsQuery = from d in db.Tags
                        orderby d.Name
                        select d;

        var selectedIds = post.Tags.Split(',').Select(n => tagsQuery.First(t => t.Name == n));
        postEditViewModel.TagsList = new MultiSelectList(tagsQuery, "Id", "Name", selectedIds);

        return View(postEditViewModel);
    }

但我得到了相同的结果。


更新 2:

我尝试更改代码(如this 教程),效果很好,但我需要使用以前的方法..

模型

    public Post Post { get; set; }
    public MultiSelectList TagsList { get; set; }

    public PostEditViewModel(Post post)
    {
        Post = post;
        var tagsQuery = from d in db.Tags
                        orderby d.Name
                        select d;
        TagsList = new MultiSelectList(tagsQuery, "Name", "Name", post.Tags.Split(','));
    }

控制器

public ActionResult Edit(int id)
    {

        Post post = db.Posts.Find(id);
        return View(new PostEditViewModel(post));
    }

查看

<div class="editor-field">
    @Html.ListBox("Tags", Model.TagsList as MultiSelectList)
</div>

有什么不同...??

【问题讨论】:

    标签: asp.net-mvc-3 razor listbox viewmodel


    【解决方案1】:

    问题在于MultiSelectList 的构造:

    new MultiSelectList(tagsQuery, "Id", "Name", post.Tags.Split(','));
    

    您正在指定元素的值将从每个标签的 Id 属性中获取,但是对于实际选择的值,您将传入一个字符串数组,该数组可能对应于标签的 Names .您也可以指定Name 为属性,从该属性中确定显示文本,这并不重要; selectedValues 参数匹配值,而不是显示文本。

    要解决此问题,请将每个标签名称投影到其对应的Id

    var selectedIds = post.Tags.Split(',').Select(n => tagsQuery.First(t => t.Name == n).Id);
    new MultiSelectList(tagsQuery, "Id", "Name", selectedIds);
    

    更新:

    糟糕,上面的代码有错误。

    我编辑了答案,在selectedIds 初始化的末尾添加了一个必需的.Id——之前的版本是选择标签,而不是 id(当然,它们是在比较不相等的苹果和橙子)。

    【讨论】:

    • @Nalaka526:请发布不能作为问题更新的确切代码。
    • @Nalaka526:谢谢,这有助于我意识到我有一个小而重要的遗漏 :) 请再看看。
    • @Nalaka526:刚刚看到你的第二次更新。区别在于我上面提到的:如果您说值将来自Tag.Name,那么您也必须为selectedValues 传递这些值。 Tag.Id 也是如此。
    • 非常感谢您的支持&很抱歉打扰您,在视图中我得到MultiSelectView,其值为selected=true,但未在列表框中选择它,任何建议??
    【解决方案2】:

    我也遇到了同样的问题,我用自己的扩展方法生成html,问题解决了

        public static MvcHtmlString ListBoxMultiSelectFor<TModel, TProperty>(
            this HtmlHelper<TModel> helper,
            Expression<Func<TModel, TProperty>> expression,
            IEnumerable<SelectListItem> selectList,
            object htmlAttributes)
        {
            return ListBoxMultiSelectFor(helper, expression, selectList, new RouteValueDictionary(htmlAttributes));
        }
    
        public static MvcHtmlString ListBoxMultiSelectFor<TModel, TProperty>(
            this HtmlHelper<TModel> helper,
            Expression<Func<TModel, TProperty>> expression,
            IEnumerable<SelectListItem> selectList,
            IDictionary<string, object> htmlAttributes)
        {
            string name = ExpressionHelper.GetExpressionText(expression);
    
            TagBuilder selectTag = new TagBuilder("select");
            selectTag.MergeAttributes(htmlAttributes);
            selectTag.MergeAttribute("id", name, true);
            selectTag.MergeAttribute("name", name, true);
            foreach (SelectListItem item in selectList)
            {
                TagBuilder optionTag = new TagBuilder("option");
                optionTag.MergeAttribute("value", item.Value);
                if (item.Selected) optionTag.MergeAttribute("selected", "selected");
                optionTag.InnerHtml = item.Text;
                selectTag.InnerHtml += optionTag.ToString();
            }
    
            return  new MvcHtmlString(selectTag.ToString());
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-16
      • 1970-01-01
      • 2012-02-02
      • 1970-01-01
      • 2014-02-27
      • 2013-06-12
      • 1970-01-01
      • 2013-12-22
      相关资源
      最近更新 更多