为什么multiselect .net mvc不显示所选值?

时间:2015-03-11 05:25:27

标签: c# asp.net-mvc asp.net-mvc-4

我无法弄清楚为什么asp mvc 4中的ListBox助手没有显示所选的值。我一直在谷歌搜索似乎没有解决问题。假设我有一个这样的控制器:

public ActionResult CreateDetailsMateria(int IdMateriaCurso)
    {
        try
        {
            MateriasModel model = new Metodos.Entidades().getMateriaById(IdMateriaCurso);
            model.listaMaterias = new Metodos.Entidades().getAllMaterias();
            int materiasNombres = model.IdMateriasNombres;
            List<SelectListItem> listadoMaterias = new List<SelectListItem>();
            listadoMaterias.Add(new SelectListItem { Text = "Elija una materia...", Value = 0.ToString(), Selected = true });
            model.listaMaterias.ForEach(t => listadoMaterias.AddRange(from U in model.listaMaterias
                                                                      where U.IdMateriasNombres.Equals(t.IdMateriasNombres)
                                                                      select new SelectListItem
                                                                      {
                                                                          Value = U.IdMateriasNombres.ToString(),
                                                                          Text = U.MateriaNombre,
                                                                          Selected = U.IdMateriasNombres.Equals(materiasNombres)
                                                                      }));

            ViewBag.ListaMaterias = listadoMaterias;
            List<DocentesModel> maestros = new List<DocentesModel>();
            maestros = new Metodos.Entidades().getDocentes();
            List<DocentesModel> maestrosSeleccionados = model.maestros;

            List<SelectListItem> listadoMaestros = new List<SelectListItem>();
            listadoMaestros.AddRange(from U in maestros
                                     select new SelectListItem
                                     {
                                         Value = U.IdMaestro.ToString(),
                                         Text = U.Nombres + " " + U.ApellidoPaterno + " " + U.ApellidoMaterno,
                                         Selected = maestrosSeleccionados.Select(t => t.IdMaestro.Equals(U.IdMaestro)).First()
                                     });
            MultiSelectList catedraticos = new MultiSelectList(listadoMaestros, "Value", "Text", listadoMaestros.Select(a => a.Selected));

            ViewBag.ListaMaestros = catedraticos;
            ViewBag.datofecha = model.Fecha.Day.ToString();
            ViewBag.hora = model.HorarioInicio.Hours.ToString();
            return PartialView(model);
        }
        catch
        {
            ViewBag.Error = "Ocurrió un error inesperado";
            return PartialView();
        }

在我看来:

@{
Layout = null;
var master = ViewBag.ListaMaestros;
var matter = ViewBag.ListaMaterias;
}
<div class="editor-field">
    @Html.ListBox("maestros", (MultiSelectList)master)
</div>

我可以看到,当我调试我的值设置正确时,并且在Visual Studio 2012中的调试器的Selected Items属性中,我可以看到selected = true值,但是当我展开第二个结果视图时(那个说会枚举可枚举的)我不再看到我的值设置为true(但我不认为这是问题,是吗?)无论如何,生成的html标记显示没有任何选项的选定属性。 有什么明显的我做错了吗?

关于@Stephen Muecke关于使用一个根本不起作用的复杂对象的评论,我想知道为什么它正确地渲染值和文本字段,无论如何,这里是构成“maestros”属性的完整类:

public class DocentesModel
{

    public int UserId { get; set; }

    public int IdMaestro { get; set; }
    public int IdMateriasCursos { get; set; }
    [Required]
    [Display(Name = "Nombre de Usuario")]
    public string UserName { get; set; }

    [Required]
    [Display(Name = "Nombres")]
    public string Nombres { get; set; }

    [Required]
    [Display(Name = "Apellido Paterno")]
    public string ApellidoPaterno { get; set; }

    [Required]
    [Display(Name = "Apellido Materno")]
    public string ApellidoMaterno { get; set; }

    [Required]
    [Display(Name = "Título por el que desea que se le llame")]
    [StringLength(5, ErrorMessage = "El {0} que escriba no debe ser más largo que {1} caracteres y debe ser menor a {2} caracteres", MinimumLength = 3)]
    public string Titulo { get; set; }

    [Required]
    [Display(Name = "Grado de Estudios")]
    public string GradoEstudios { get; set; }

    [Required]
    [Display(Name = "Número telefónico a diez dígitos")]
    [DataType(DataType.PhoneNumber)]
    [RegularExpression("^[0-9]{10}", ErrorMessage = "El teléfono que escriba no debe contener exactamente 10 dígitos, sin guiones")]
    public string Telefono { get; set; }

    [Required]
    [Display(Name = "Email")]
    [DataType(DataType.EmailAddress, ErrorMessage = "El correo electrónico que escribió no es válido")]
    public string Email { get; set; }

    [Required(ErrorMessage = "El campo Dirección es obligatorio")]
    [Display(Name = "Dirección (favor de incluir el código postal)")]
    public string Direccion { get; set; }

    [Required]
    [Display(Name = "RFC")]
    [RegularExpression(@"^([A-ZÑ\x26]{3,4}([0-9]{2})(0[1-9]|1[0-2])(0[1-9]|1[0-9]|2[0-9]|3[0-1]))([A-Z\d]{3})?$", ErrorMessage = "El RFC no es válido")]
    public string RFC { get; set; }

    [Required]
    [Display(Name = "No. de cuenta bancaria")]
    [StringLength(20, ErrorMessage = "El {0} debe contener al menos {2} caracteres", MinimumLength = 10)]
    public string CtaBancaria { get; set; }

    [Required]
    [Display(Name = "Banco en que tiene su cuenta bancaria")]
    public string BancoCtaBancaria { get; set; }

    [Required]
    [Display(Name="Clabe interbancaria")]
    [StringLength(18, ErrorMessage = "El {0} debe contener al menos {1} caracteres")]
    public string ClabeBancaria { get; set; }

    [Required]
    [Display(Name = "Descripcion")]
    public string Descripcion { get; set; }

    public string Fotografia { get; set; }
    public string FotografiaNombre { get; set; }

    [Display(Name = "Página Personal (Opcional)")]
    [DataAnnotationsExtensions.Url(UrlOptions.RequireProtocol, ErrorMessage = "Por favor introduzca un Url válido")]
    public string PagPersonal { get; set; }

    [Display(Name = "Dirección de Facebook (Opcional)")]
    [DataAnnotationsExtensions.Url(UrlOptions.RequireProtocol, ErrorMessage = "Por favor introduzca un Url válido")]
    public string CtaFacebook { get; set; }

    [Display(Name = "Dirección de Twitter (Opcional)")]
    [DataAnnotationsExtensions.Url(UrlOptions.RequireProtocol, ErrorMessage = "Por favor introduzca un Url válido")]
    public string CtaTwitter { get; set; }

    [Required]
    [DataType(DataType.DateTime)]
    public DateTime FechaAlta { get; set; }

    [Required]
    [DataType(DataType.DateTime)]
    public DateTime FechaUltimoCambio { get; set; }

    [Display(Name="Inhabilitar")]
    public bool? Inhabilitado { get; set; }

    [Display(Name = "Activar cuenta")]
    public bool Activar { get; set; }
}

我不认为这是一个复杂的对象,它只是一个基元的集合。 @Stephen Muecke你能澄清一下,因为在同一个解决方案中,我可以使用一个简单的DropDownList来做以下事情:

var allRoles = roles.GetAllRoles().Select(x => new SelectListItem
            {
                Text = x,
                Value = x
            }).ToList<SelectListItem>();
            allRoles.Add(new SelectListItem { Text = "Escoja...", Value = "", Selected = true });

然后选择值得到的。 谢谢你的时间。

**************************用我目前所做的更新************ *******

关注@Stephen Muecke和@ 111评论,我创建了一个这样的类: 好吧,我到目前为止所做的就是创建一个像这样的新类

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

然后我在我的控制器中做了:

List<DocentesListasModel> listadoMaestros = new List<DocentesListasModel>();
            listadoMaestros.AddRange(from U in maestros
                                     select new DocentesListasModel
                                     {
                                      Id = U.IdMaestro,
                                      Name = U.Nombres+ " "+ U.ApellidoPaterno + " "+U.ApellidoMaterno
                                     });
            List<DocentesModel> seleccionadosMasters = maestrosSeleccionados.Where(p => listadoMaestros.Any(t => t.Id.Equals(p.IdMaestro))).ToList();
            MultiSelectList catedraticos = new MultiSelectList(listadoMaestros, "Id", "Name", listadoMaestros.Where(t=> seleccionadosMasters.Any(s=> s.IdMaestro.Equals(t.Id))).Select(x => x.Id));

但仍无济于事。它正确地编译和调试,但它可能过于复杂,将其与提供的示例进行比较。问题是我现在无法设计另一个模型而且我不能在局部视图中进一步划分,因为我已经在使用局部视图了。

2 个答案:

答案 0 :(得分:1)

可能这个简单的例子可以帮到你:

ViewModel:

   public class SampleViewModel
    {
        public int Id { get; set; }

        public string Name { get; set; }
    }

在Controller中设置SelectList,如下所示:

 var sampleViewModelList= new List<SampleViewModel>() {
                    new SampleViewModel() {Id=1, Name="A"},
                    new SampleViewModel() {Id=2, Name="B"},
                    new SampleViewModel() {Id=3, Name="C"}
                };

 ViewBag.SomeList = new SelectList(sampleViewModelList, "Id", "Name",sampleViewModelList.First(x => x.Id == 2).Id); 

在视图中:

@Html.ListBox("maestros", ViewBag.SomeList as SelectList)

答案 1 :(得分:1)

首先创建一个代表您正在编辑的视图模型(并删除所有ViewBag内容)

查看模型

public class MateriasViewModel
{
  public int[] SelectedMaestros { get; set; } // for binding the selected values
  public SelectList MaestrosList { get; set; } // for displaying the options
  .... // other properties to display/edit in the view
}

控制器

public ActionResult CreateDetailsMateria(int IdMateriaCurso)
{
  MateriasViewModel model = new MateriasViewModel();
  // Get the data model and map the properties to the view model
  ....

  // Cant understand some of your code so you need to set the values of the following line
  model.SelectedMaestros = new int[] { 2, 4 };

  // Assign the select list (this is all that's required!)
  var listaMaterias = new Metodos.Entidades().getAllMaterias();
  model.MaestrosList = new SelectList(listaMaterias, "IdMateriasNombres", "MateriaNombre");
  return View(model)
}

查看

@model MateriasViewModel
@using(Html.BeginForm())
{
  ....
  @Html.ListBoxFor(m => m.SelectedMaestros, Model.MaestrosList)
  ....
}

如果属性SelectedMaestros的值与属性IdMateriasNombres定义的任何选项值匹配,则在渲染视图时,将在列表框中选择这些选项。例如,如果生成的html是

<select name="SelectedMaestros">
  <option value="1">Some text</option>
  <option value="2">Some text</option>
  <option value="3">Some text</option>
  <option value="4">Some text</option>
</select>

SelectedMaestros的值为{ 2, 4 },然后将选择第2和第4个选项