Asp.net mvc 如何在ASP.NET MVC中使用SelectListItem通过列表框或复选框显示选项

Asp.net mvc 如何在ASP.NET MVC中使用SelectListItem通过列表框或复选框显示选项,asp.net-mvc,selectlistitem,html.listboxfor,Asp.net Mvc,Selectlistitem,Html.listboxfor,我读了几篇关于如何向用户展示选择的文章。有些人使用ListBoxFor,有些人使用CheckBoxFor,还有一种叫做MultiSelectList的东西 让我感到困惑的是,每个示例似乎都是以完全不同的方式完成的,它们中没有一个实际使用内置的SelectListItem类,而是始终创建自己的类 所以我本来打算发布一个问题,要求进行一般性的澄清,但我认为它只会代表所有其他各种各样的帖子和重复的内容 因此,让我重新表述一下:如何使用列表或多选列表向用户显示选项列表,包括将选项显示为复选框列表的选项

我读了几篇关于如何向用户展示选择的文章。有些人使用ListBoxFor,有些人使用CheckBoxFor,还有一种叫做MultiSelectList的东西

让我感到困惑的是,每个示例似乎都是以完全不同的方式完成的,它们中没有一个实际使用内置的SelectListItem类,而是始终创建自己的类

所以我本来打算发布一个问题,要求进行一般性的澄清,但我认为它只会代表所有其他各种各样的帖子和重复的内容

因此,让我重新表述一下:如何使用列表或多选列表向用户显示选项列表,包括将选项显示为复选框列表的选项

换句话说,如果我的模型中有以下两项,我将如何将它们显示为典型的选择列表框或典型的复选框

public List<SelectListItem> Widgets1 { get; set; }
public MultiSelectList Widgets2 { get; set; }

让我们从模型开始。这是非常基本的,您可以看到,我只是创建了3个列表来存储相同的数据

// ------------------------------------------------------------------------
[HttpGet]       //Display the Edit view
public ActionResult Edit()
{
    FooModel myModel = new FooModel;

    //For testing, here I'm going to Inject some Choices
    //So first we build a list of them
    List<SelectListItem> myChoices = new List<SelectListItem>();
    for (Int32 myIndex = 1; myIndex < 15; myIndex++)
    {
        SelectListItem myChoice = new SelectListItem();
        myChoice.Value = myIndex.ToString();
        myChoice.Text = "Choice " + myIndex.ToString();
        if ((myIndex % 2) == 0)
        {
            myChoice.Selected = true;
        }
        else
        {
            myChoice.Selected = false;
        }
        myChoices.Add(myChoice);
    }

    String[] mySelections = myChoices.Where(x => x.Selected == true).ToArray().Select(x => x.Value).ToArray();

    //Now we use that same list to populate all 3 variations in our model
    myModel.WidgetsAsCheckList.AddRange(myChoices);
    myModel.WidgetsAsListBox.AddRange(myChoices);
    myModel.WidgetMultiSelectList = new MultiSelectList(myChoices, "Value", "Text", mySelections); 

    return View(myModel);
}
这里的主要区别在于,我阅读的所有示例,人们都在创建自己的项目类,我只想使用内置的SelectListItem类

public class FooModel
{
  [Display(Name = "WidgetCheckList")]
  public List<SelectListItem> WidgetsAsCheckList { get; set; }

  [Display(Name = "WidgetListBox")]
  public List<SelectListItem> WidgetsAsListBox { get; set; }

  [Display(Name = "WidgetMultiSelectList")]
  public MultiSelectList WidgetMultiSelectList { get; set; }

  //We have to create a bucket that not only some how 
  //auto-magically knowns what has been pre-selected in the 
  //original list, but provides the view something to store
  //the new selections in when returning to the controller.
  //I have to admit, I have no idea how this knows what was
  //pre-selected, but being new at MVC, there are things I 
  //just have to leave it as a mystery becuase it just works.

  [HiddenInput(DisplayValue = false)]
  public List<string> userSelectionsAsListBox { get; set; }

  [HiddenInput(DisplayValue = false)]
  public List<string> userSelectionsAsMultiSelectList { get; set; }

  public FooModel()
  {
    this.WidgetsAsCheckList = new List<SelectListItem>();
    this.WidgetsAsListBox = new List<SelectListItem>();
    this.WidgetMultiSelectList = new MultiSelectList(new List<SelectListItem>());
  }
}   
对于控制器,因为这是一个学习测试,所以我只是整理了数据。这里的关键是,我构建了一个SelectListItems列表,然后使用该列表填充模型的所有3个演示字段,以显示使用相同数据的3种不同方式

// ------------------------------------------------------------------------
[HttpGet]       //Display the Edit view
public ActionResult Edit()
{
    FooModel myModel = new FooModel;

    //For testing, here I'm going to Inject some Choices
    //So first we build a list of them
    List<SelectListItem> myChoices = new List<SelectListItem>();
    for (Int32 myIndex = 1; myIndex < 15; myIndex++)
    {
        SelectListItem myChoice = new SelectListItem();
        myChoice.Value = myIndex.ToString();
        myChoice.Text = "Choice " + myIndex.ToString();
        if ((myIndex % 2) == 0)
        {
            myChoice.Selected = true;
        }
        else
        {
            myChoice.Selected = false;
        }
        myChoices.Add(myChoice);
    }

    String[] mySelections = myChoices.Where(x => x.Selected == true).ToArray().Select(x => x.Value).ToArray();

    //Now we use that same list to populate all 3 variations in our model
    myModel.WidgetsAsCheckList.AddRange(myChoices);
    myModel.WidgetsAsListBox.AddRange(myChoices);
    myModel.WidgetMultiSelectList = new MultiSelectList(myChoices, "Value", "Text", mySelections); 

    return View(myModel);
}
现在,对于视图,我显示每个列表。第一个当然是复选框,第二个和第三个是列表框,但使用不同的底层对象

@* This displays the "list" of SelectListItems as Checkboxes but we have to do alot more work *@
<div class="form-group">
    @Html.LabelFor(model => model.WidgetsAsCheckList, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        <div class="form-control" style="overflow-y: scroll; height: 25em; width:280px;">
            @for (var myIndex = 0; myIndex < Model.WidgetsAsCheckList.Count; myIndex++)
            {
                @Html.CheckBoxFor(cc => cc.WidgetsAsCheckList[myIndex].Selected, new { htmlAttributes = new { @class = "form-control" } })
                @Html.HiddenFor(cc => cc.WidgetsAsCheckList[myIndex].Value, new { htmlAttributes = new { @class = "form-control" } })
                @Html.DisplayFor(cc => cc.WidgetsAsCheckList[myIndex].Text, new { htmlAttributes = new { @class = "form-control" } })
                <br />
            }
        </div>
    </div>

</div>

 @* This displays the "list" of SelectListItems as list box that does all the work for us *@
<div class="form-group">
    @Html.LabelFor(model => model.WidgetsAsListBox, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">                
        @Html.ListBoxFor(model => model.userSelectionsAsListBox, Model.WidgetsAsListBox, new { @class = "form-control", size = 25 })
    </div>
</div>

@* This displays the "MultiSelectList" as list box that does all the work for us *@
<div class="form-group">
    @Html.LabelFor(model => model.WidgetMultiSelectList, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.ListBoxFor(model => model.userSelectionsAsMultiSelectList, Model.WidgetMultiSelectList, new { @class = "form-control", size = 25 })
    </div>
</div>
最后,当用户做出自己的选择或选择预先选择的并点击submit时,我们可以通过简单的

// ---------------------------------------------------------------------
[HttpPost]       
[ValidateAntiForgeryToken]
public ActionResult Edit(FooModel myFooModel)
{

    List<string> SelectedItemsFromListBox = myFooModel.userSelectionsAsListBox;

    List<string> SelectedItemsFromMultiSelectList = myFooModel.userSelectionsAsMultiSelectList;

    List<string> SelectedItemsFromCheckList = myFooModel.WidgetsAsCheckList.Where(x => x.Selected == true).ToList().Select(x => x.Value).ToList();

}

警告。。。我只是想指出,一旦你有太多的选择,复选框选项基本上会挂起。e、 g.将我的循环更改为500,它基本上不会提交

问题可追溯到CheckBoxFor行的验证。这可以通过将一行更改为

                        @Html.CheckBoxFor(cc => cc.WidgetsAsCheckList[myIndex].Selected, new { data_val = "false",  htmlAttributes = new { @class = "form-control" } })

如果我这样做,我可以在检查列表中有1500个项目,提交在3秒内完成

您甚至没有问任何问题!这个问题或你的任何回答都无助于任何人。你是对的。我看到Stack Overflow向我展示了一个选项,可以回答你自己的问题并分享知识,所以我猜这就是本文的内容。如果你真的回答了一个问题,那就好了,但是没有问题,所以你的自我回答毫无意义。我有点困惑。。这像杰帕迪吗?我是否必须说明如何在清单中显示数据?然后转过身来,说这是如何你不明白这是什么。它的目标是建立一个问答库。一个问题需要一个问题的明确陈述,与之相关的代码,以及对什么不起作用的解释。你什么都没做。如果你想写你自己的博客,尽管写吧,但不要用它。