1

我正在寻找一种方法来处理动态数量的列表框,但似乎无法找到搜索 SO 或 Google 的答案。

考虑以下 ViewModel

public class IndexViewModel
{
    public List<Option> Options { get; set; }
    public List<int> SelectedOptions { get; set; } 
}

public class Option
{
    public OptionType Type { get; set; }
    public int Id { get; set; }
    public string Name { get; set; }
}

public class OptionType
{
    public int Id { get; set; }
    public string Name { get; set; }
}

然后可以使用以下剃刀视图呈现

@model MvcApplication2.Models.IndexViewModel
@using(Html.BeginForm())
{
    @Html.ListBoxFor(model => model.SelectedOptions, new MultiSelectList(Model.Options, "Id", "Name"), new {Multiple = "multiple"})
    <input type="submit" value="Submit" class="submit" />
}

并使用以下操作方法处理

public ActionResult Index()
{
    var model = new IndexViewModel();
    var colourType = new OptionType {Id = 0, Name = "Colour"};
    var shapeType = new OptionType {Id = 1, Name = "Shape"};
    model.Options = new List<Option>
        {
            CreateOption(0, "Red", colourType),
            CreateOption(1, "Green", colourType),
            CreateOption(2, "Circle", shapeType),
            CreateOption(2, "Square", shapeType)
        };
    return View(model);
}

[HttpPost]
public ActionResult Index(IndexViewModel model)
{
    //Do something with the posted model
    return RedirectToAction("Index");
}

private static Option CreateOption(int id, string name, OptionType colourType)
{
    return new Option
    {
        Id = id,
        Name = name,
        Type = colourType
    };
}

如果我要通过更改模型和视图来将Options Based on theirOptionType分成多个列表框

public class IndexViewModel
{
    public Dictionary<string, List<Option>> Options { get; set; }

    //public List<int> SelectedOptions { get; set; } 
}

@model MvcApplication2.Models.IndexViewModel
@using (Html.BeginForm())
{
    <ul>
        @foreach (var optList in Model.Options)
        {
            <li>
                @optList.Key : @Html.ListBoxFor(model => model.SelectedOptions, new MultiSelectList(optList.Value, "Id", "Name"), new { Multiple = "multiple" })
            </li>   
        }
    </ul>
    <input type="submit" value="Submit" class="submit" />
}

并修改支持的控制器方法

    public ActionResult Index()
{
    var model = new IndexViewModel();
    model.Options = new Dictionary<string, List<Option>>
        {
            {"Colour", CreateColourList()},
            {"Shape", CreateShapeList()}
        };
    return View(model);
}

[HttpPost]
public ActionResult Index(IndexViewModel model)
{
    return RedirectToAction("Index");
}


private static List<Option> CreateColourList()
{
    var colourType = new OptionType { Id = 0, Name = "Colour" };

    return new List<Option>
        {
            CreateOption(0, "Red", colourType),
            CreateOption(1, "Green", colourType),
        };
}
private static List<Option> CreateShapeList()
{
    var shapeType = new OptionType { Id = 1, Name = "Shape" };
    return new List<Option>
        {
            CreateOption(2, "Circle", shapeType),
            CreateOption(2, "Square", shapeType)
        };
}
private static Option CreateOption(int id, string name, OptionType colourType)
{
    return new Option
    {
        Id = id,
        Name = name,
        Type = colourType
    };
}

我将如何在视图模型中定义 Selected 选项,以便它绑定到 HttpPost 索引操作中?

另外,我想知道如何更改 SelectedOptions 类型以包含 Option 实例而不是整数,但最初这并不太重要,整数的工作解决方案将有助于缓解我的头痛。

编辑:澄清一下,虽然我在上面的示例中明确定义了选项,但在实际代码中,这些实际上是从数据库加载的,并且可能有任意数量的Options 和OptionTypes

提前致谢!

4

1 回答 1

1

一种可能性是使用视图模型:

public class MyViewModel
{
    public string Key { get; set; }
    public List<int> SelectedValues { get; set; }
    public List<Option> Options { get; set; }
}

public class IndexViewModel
{
    public List<MyViewModel> Options { get; set; }
}

您的控制器操作将填充并传递给视图:

public ActionResult Index()
{
    var model = new IndexViewModel();
    model.Options = new[]
    {
        new MyViewModel { Key = "Colour", Options = CreateColourList() },
        new MyViewModel { Key = "Shape", Options = CreateShapeList() },
    }.ToList(); 
    return View(model);
}

最后在视图中,您将使用此视图模型生成正确的标记:

@using(Html.BeginForm())
{
    <ul>
        @for (int i = 0; i < Model.Options.Count; i++)
        {
            <li>
                @Html.HiddenFor(model => model.Options[i].Key)
                @Model.Options[i].Key
                :
                @Html.ListBoxFor(
                    model => model.Options[i].SelectedValues,  
                    new MultiSelectList(Model.Options[i].Options, "Id", "Name")
                )
            </li>   
        }
    </ul>
    <input type="submit" value="Submit" class="submit" />
}

现在,当提交表单时,您的 HttpPost 操作将IndexViewModel正确绑定相应的实例,并包含每组选项的Key和集合。SelectedValues

于 2013-10-29T09:15:31.447 回答