简体   繁体   English

MVC Razor MultiSelectList获取/设置SelectedValue

[英]MVC Razor MultiSelectList Getting/Setting SelectedValue

I'm using erichynds Multi Select Widget to create a nice style for my MultiSelectList. 我正在使用erichynds Multi Select Widget为我的MultiSelectList创建一个不错的样式。 But my issue (appears) to be unrelated. 但是我的问题(似乎)是无关紧要的。

I am trying to loop through each DemographicQuestionFilter question, list out the DemographicResponseFilter response and be able to get/post the selected items along with my DemographicFilterViewModel model. 我试图遍历每个DemographicQuestionFilter问题,列出DemographicResponseFilter响应,并能够获取/发布所选项目以及我的DemographicFilterViewModel模型。 The issue I am having is that when I set the filters for item-1 (index 0) in the list it works fine, when I set item-2 (index 1) it only works if item-1 is also set, if item-1 is not set then the DemographicFilters object is null. 我遇到的问题是,当我在列表中为item-1(索引0)设置过滤器时,它可以正常工作;当我设置item-2(索引1)时,它也仅在同时设置了item-1的情况下有效,如果未设置-1,则DemographicFilters对象为null。 I'm assuming I can switch up types, or that I'm missing something basic here. 我假设我可以切换类型,或者我在这里错过了一些基本的知识。

How can I make it so that the list containing the selected items for n Question is not dependent n-1 also having a selected item? 如何使包含n个问题的所选项目的列表不依赖于n-1个也具有所选项目的列表?

Here are my ViewModel objects: 这是我的ViewModel对象:

Parent: 上级:

public class DemographicFilterViewModel
{
    public int TaskID { get; set; }
    public List<DemographicQuestionFilter> DemographicFilters { get; set; }
}

Child: 儿童:

public class DemographicQuestionFilter
{   
    public string Question { get; set; }

    public List<DemographicResponseFilter> Responses { get; set; }

    public List<SelectListItem> selectListItems { get; set; }

    public List<int> SelectedItems { get; set; }
}

Grandchild: 孙子:

public class DemographicResponseFilter
{
    public int ResponseID { get; set; }
    public string Response { get; set; }
}




View: 视图:

@Html.HiddenFor(m => m.TaskID)
if (Model.DemographicFilters != null)
{
    for (int i = 0; i < Model.DemographicFilters.Count; i++)
    {
        @Html.HiddenFor(model => model.DemographicFilters[i].SelectedItems)
        @Html.DisplayTextFor(m => m.DemographicFilters[i].Question)
        <br />
        @Html.ListBoxFor(model => model.DemographicFilters[i].SelectedItems, new MultiSelectList(Model.DemographicFilters[i].Responses, "ResponseID", "Response", Model.DemographicFilters[i].SelectedItems),  new { Multiple = "multiple" })
        <br />
        <br />
    }
}

Here is what is rendered to the screen (just so you can try to follow what I am doing): http://i.imgur.com/ZefpLy1.png?1 这是渲染到屏幕上的内容(只是您可以尝试遵循我在做什么): http : //i.imgur.com/ZefpLy1.png?1

Edit: The issue is when the View posts back to the controller, the View displays correctly, but on HttpPost the values in [n]SelectedItems are dependent on [n-1]SelectedItems having a value, 编辑:问题是,当视图发回控制器时,视图正确显示,但是在HttpPost上,[n] SelectedItems中的值取决于具有值的[n-1] SelectedItems,

If [i]SelectedItems is blank (nothing selected) then every [>i]SelectedItems is null, even when the values are correctly set in the HttpGet... 如果[i] SelectedItems为空白(未选择任何内容),则即使[Http]中正确设置了值,每个[> i] SelectedItems也为null。

HTMLHelper Extension: HTMLHelper扩展:

#region Usings

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

#endregion

namespace Extensions
{
    public static class HtmlHelperExtensions
    {
        public static MvcHtmlString HiddenEnumerableFor<TModel, TEnumType>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, IEnumerable<TEnumType>>> expression)
        {
            return htmlHelper.Hidden(htmlHelper.NameFor(expression).ToHtmlString(),
                string.Join(",", expression.Compile().Invoke(htmlHelper.ViewData.Model) ?? new TEnumType[0]));
        }
    }
}



HiddenFor cannot be used for ListBoxFor so here is the workaround I tried to fix the issue. HiddenFor不能用于ListBoxFor,因此这是我尝试解决此问题的解决方法。

Replaced 已更换

  @Html.HiddenFor(model => filter.SelectedItems)

With

  @Html.Hidden(string.Format("DemographicFilters[{0}].SelectedItems", i), "-1")

Problem with this approach is that your DemographicFilters.SelectedItems will have an extra row -1 added to it, need to add code to exclude -1 row. 这种方法的问题是,您的DemographicFilters.SelectedItems将添加一个额外的行-1,需要添加代码以排除-1行。

My answer is an extension on what Vasanth Sundaralingam posted in his answer, that HiddenFor won't work with arrays. 我的答案是对Vasanth Sundaralingam在其答案中发布的内容的扩展,即HiddenFor将不适用于数组。 I went ahead and created a function that behaves like a hiddenFor for enumerable properties. 我继续为可枚举的属性创建了一个行为类似于hiddenFor的函数。

@functions
{
    public MvcHtmlString HiddenEnumerableFor<TModel, TEnumType>(
        HtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, IEnumerable<TEnumType>>> expression) 
    {

        return htmlHelper.Hidden(htmlHelper.NameFor(expression).ToHtmlString(),
            string.Join(",", expression.Compile().Invoke(htmlHelper.ViewData.Model) ?? new TEnumType[0]));
    }
}

Replace 更换

@Html.HiddenFor(model => filter.SelectedItems)

With

@HiddenEnumerableFor(Html, m => m.DemographicFilters[i].SelectedItems)

You could also convert this into an extension method by adding it to a static class, and adding this before the first parameter. 你也可以将它添加到一个静态类,并增加转换成一个扩展方法这this第一个参数之前。 That way it would look like very similar to HiddenFor 这样看起来就和HiddenFor非常相似

@Html.HiddenEnumerableFor(m => m.DemographicFilters[i].SelectedItems)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM