我正在寻找一种处理动态数量的列表框的方法,似乎无法找到搜索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
};
}
如果我通过更改模型和视图将Option
基于OptionType
基于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
};
}
并修改支持控制器方法
Option
如何在视图模型中定义Selected选项,以便它在HttpPost Index Action中绑定?
另外作为一个额外的我想知道如何更改SelectedOptions类型以包含Option实例而不是整数但最初这不是太重要,一个有整数的工作解决方案将有助于缓解我的头痛。
编辑:只是为了澄清,虽然我在上面的示例中明确定义了选项,但在实际代码中这些实际上是从数据库加载的,并且可以有任意数量的OptionType
和{{1}} s
提前致谢!
答案 0 :(得分: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
集合。