Usar el asistente DropDownList con ASP.NET MVC

por Rick Anderson

Este tutorial le enseñará los aspectos básicos de trabajar con los asistentes DropDownList y ListBox en aplic. web de ASP.NET MVC. Es posible usar Microsoft Visual Web Developer 2010 Express Service Pack 1, que es una versión gratuita de Microsoft Visual Studio, para seguir el tutorial. Antes de empezar, asegúrese de haber instalado los requisitos previos que se enumeran a continuación. Para instalarlos todos, haga clic en el vínculo siguiente: Instalador de plataforma web. Como alternativa, instale individualmente los requisitos previos con los vínculos siguientes:

Si usa Visual Studio 2010 en lugar de Visual Web Developer 2010, instale los requisitos previos haciendo clic en el vínculo siguiente: Requisitos previos de Visual Studio 2010. En este tutorial se supone que completó el tutorial Introducción a ASP.NET MVC o eltutorial de ASP.NET MVC Music Store o que está familiarizado con el desarrollo de ASP.NET MVC. Este tutorial comienza con un proyecto modificado desde el tutorial de ASP.NET MVC Music Store.

Un proyecto de Visual Web Developer con el código fuente de C# completo del tutorial está disponible para acompañar este tema. Descarga.

Lo que creará

Creará métodos de acción y vistas que usan el asistente DropDownList para seleccionar una categoría. También usará jQuery para agregar un cuadro de diálogo de inserción de categoría que se podrá usar cuando se necesite una nueva categoría (como género o artista). A continuación, se muestra una captura de pantalla de la vista Crear que muestra vínculos para agregar un nuevo género y un nuevo artista.

Image using drop down list helper

Habilidades que aprenderá

Aprenderá lo siguiente:

  • Cómo usar el asistente DropDownList para seleccionar datos de categoría.
  • Cómo agregar un cuadro de diálogo jQuery para agregar nuevas categorías.

Introducción

Empiece por descargar el proyecto de inicio con el vínculo siguiente: Descargar. En el Explorador de Windows, haga clic con el botón derecho en el archivo DDL_Starter.zip y seleccione Propiedades. En el cuadro de diálogo Propiedades de DDL_Starter.zip, seleccione Desbloquear.

Image of properties dialog box select unblock

Haga clic con el botón derecho en el archivo DDL_Starter.zip y seleccione Extraer todo para descomprimir el archivo. Abra el archivo StartMusicStore.sln con Visual Web Developer 2010 Express ("Visual Web Developer" o "VWD" para abreviar) o Visual Studio 2010.

Presione CTRL+F5 para ejecutar la aplicación y haga clic en el vínculo Probar.

Image of application test link

Seleccione el vínculo Seleccionar categoría de película (simple). Se muestra una lista de selección Tipo de película, con el valor Comedia seleccionado.

Image of movie type select list

Haga clic con el botón derecho en el explorador y seleccione Ver origen. Se muestra el código HTML de la página. El código siguiente muestra el código HTML del elemento seleccionado.

<form action="/Home/CategoryChosen" method="get">

<fieldset>Movie Type <select id="MovieType" name="MovieType">

<option value=""></option>

<option value="0">Action</option>

<option value="1">Drama</option>

<option selected="selected" value="2">Comedy</option>

<option value="3">Science Fiction</option>

</select>

<p><input type="submit" value="Submit" /> </p>

</fieldset>

</form>

Es posible ver que cada elemento de la lista de selección tiene un valor (0 para Acción, 1 para Drama, 2 para Comedia y 3 para Ciencia Ficción) y un nombre para mostrar (Acción, Drama, Comedia y Ciencia Ficción). El código anterior es HTML estándar para una lista de selección.

Cambie la lista de selección a Drama y presione el botón Enviar. La dirección URL del explorador es http://localhost:2468/Home/CategoryChosen?MovieType=1 y la página muestra Seleccionó: 1.

Image of U R L in browser

Abra el archivo Controllers\HomeController.cs y examine el método SelectCategory.

public ActionResult SelectCategory() {

     List<SelectListItem> items = new List<SelectListItem>();

     items.Add(new SelectListItem { Text = "Action", Value = "0"});

     items.Add(new SelectListItem { Text = "Drama", Value = "1" });

     items.Add(new SelectListItem { Text = "Comedy", Value = "2", Selected = true });

     items.Add(new SelectListItem { Text = "Science Fiction", Value = "3" });

     ViewBag.MovieType = items;

     return View();

 }

El asistente DropDownList usado para crear una lista de selección HTML requiere un IEnumerable<SelectListItem >, ya sea explícita o implícitamente. Es decir, es posible pasar IEnumerable<SelectListItem > explícitamente al asistente DropDownList o bien agregar IEnumerable<SelectListItem > a ViewBag con el mismo nombre para SelectListItem que la propiedad de modelo. Pasar SelectListItem implícitamente y explícitamente se trata en la siguiente parte del tutorial. El código anterior muestra la manera más sencilla posible para crear un IEnumerable<SelectListItem > y rellenarlo con texto y valores. Tenga en cuenta que ComedySelectListItem tiene la propiedad Seleccionado establecida en true; esto hará que la lista de selección representada muestre Comedia como el elemento seleccionado en la lista.

El IEnumerable<SelectListItem > creado anteriormente se agrega a ViewBag con el nombre MovieType. Así es como pasamos el IEnumerable<SelectListItem > implícitamente al asistente DropDownList que se muestra a continuación.

Abra el archivo Views\Home\SelectCategory.cshtml y examine el marcado.

@{

    ViewBag.Title = "Category Select";

    Layout = "~/Views/Shared/_Simple_Layout.cshtml";

}

@using (Html.BeginForm("CategoryChosen", "Home", FormMethod.Get)) {

    <fieldset>

            Movie Type

            @Html.DropDownList("MovieType")

        <p>

            <input type="submit" value="Submit" />

        </p>

    </fieldset>

}

En la tercera línea, se establece el diseño en Views/Shared/_Simple_Layout.cshtml, que es una versión simplificada del archivo de diseño estándar. Se hace para mantener el HTML representado y la visualización de forma simple.

En este ejemplo, no se cambia el estado de la aplicación, por lo que enviaremos los datos mediante HTTP GET, no HTTP POST. Consulte la sección de W3C Lista de comprobación rápida para elegir HTTP GET o POST. Dado que no estamos cambiando la aplicación y publicando el formulario, se usa la sobrecarga Html.BeginForm, que nos permite especificar el método de acción, el controlador y el método de formulario (HTTP POST o HTTP GET). Normalmente, las vistas contienen la sobrecarga de Html.BeginForm que no toma parámetros. La versión sin parámetros tiene como valor predeterminado publicar los datos del formulario en la versión POST del mismo método de acción y controlador.

La línea siguiente

@Html.DropDownList("MovieType")

pasa un argumento de cadena al asistente DropDownList. Esta cadena, "MovieType" en nuestro ejemplo, hace dos cosas:

  • Proporciona la clave para que el asistente DropDownList encuentre IEnumerable<SelectListItem > en ViewBag.
  • Está enlazado a datos al elemento de formulario MovieType. Si el método de envío fuera HTTP GET, MovieType será una cadena de consulta. Si el método de envío fuera HTTP POST, MovieType se agregará en el cuerpo del mensaje. En la imagen siguiente se muestra la cadena de consulta con el valor 1.

Image of query string with value of 1

El código siguiente muestra el método CategoryChosen al que se envió el formulario.

public ViewResult CategoryChosen(string MovieType) {

    ViewBag.messageString = MovieType;

    return View("Information");

}

Vuelva a la página de prueba y seleccione el vínculo HTML SelectList. La página HTML representa un elemento de selección similar a la página de prueba de ASP.NET MVC simple. Haga clic con el botón derecho en la ventana del explorador y seleccione Ver origen. El marcado HTML de la lista de selección es esencialmente idéntico. Pruebe la página HTML: funciona como el método de acción ASP.NET MVC y la vista que probamos anteriormente.

Mejora de la lista de selección Películas con enumeraciones

Si las categorías de la aplicación son fijas y no cambiarán, aproveche las enumeraciones para que el código sea más sólido y fácil de ampliar. Al agregar una nueva categoría, se genera el valor de categoría correcto. Se evitan errores de copiar y pegar al agregar una nueva categoría, pero se olvida de actualizar el valor de categoría.

Abra el archivo Controllers\HomeController.cs y examine el código siguiente:

public enum eMovieCategories { Action, Drama, Comedy, Science_Fiction };

private void SetViewBagMovieType(eMovieCategories selectedMovie) {

    IEnumerable<eMovieCategories> values = 

                      Enum.GetValues(typeof(eMovieCategories))

                      .Cast<eMovieCategories>();

    IEnumerable<SelectListItem> items =

        from value in values

        select new SelectListItem

        {

            Text = value.ToString(),

            Value = value.ToString(),

            Selected = value == selectedMovie,

        };

    ViewBag.MovieType = items;

}

public ActionResult SelectCategoryEnum() {

    SetViewBagMovieType(eMovieCategories.Drama);

    return View("SelectCategory");

}

La enumeracióneMovieCategories captura los cuatro tipos de película. El método SetViewBagMovieType crea IEnumerable<SelectListItem > a partir de la eMovieCategoriesenumeración y establece la propiedad Selected del parámetro selectedMovie. El método de acción SelectCategoryEnum usa la misma vista que el método de acción SelectCategory.

Vaya a la página Prueba y haga clic en el vínculo Select Movie Category (Enum). Esta vez, en lugar de mostrar un valor (número), se muestra una cadena que representa la enumeración.

Publicar valores de enumeración

Los formularios HTML se usan normalmente para publicar datos en el servidor. En el código siguiente se muestran las versiones HTTP GET y HTTP POST del método SelectCategoryEnumPost.

public ActionResult SelectCategoryEnumPost() {

    SetViewBagMovieType(eMovieCategories.Comedy);

    return View();

}

[HttpPost]

public ActionResult SelectCategoryEnumPost(eMovieCategories MovieType) {

    ViewBag.messageString = MovieType.ToString() +

                            " val = " + (int)MovieType;

    return View("Information");

}

Al pasar una enumeración eMovieCategories al POST método, es posible extraer el valor y la cadena de enumeración. Ejecute el ejemplo y vaya a la página Prueba. Haga clic en el vínculo Select Movie Category(Enum Post). Seleccione un tipo de película y, a continuación, presione el botón Enviar. La pantalla muestra el valor y el nombre del tipo de película.

Image of value and name of movie type

Crear un elemento de selección de sección múltiple

El asistente HTML ListBox representa el elemento HTML <select> con el atributo multiple, lo que permite a los usuarios realizar varias selecciones. Vaya al vínculo Prueba y, a continuación, seleccione el vínculo Selección múltiple de país. La interfaz de usuario representada permite seleccionar varios países. En la imagen siguiente, se seleccionan Canadá y China.

Image of multiple selections drop down list

Examen del código MultiSelectCountry

Examine el código siguiente del archivo Controllers\HomeController.cs.

private MultiSelectList GetCountries(string[] selectedValues) {

    List<Country> Countries = new List<Country>()

        {

            new Country() { ID = 1, Name= "United States" },

            new Country() { ID = 2, Name= "Canada" },

            new Country() { ID = 3, Name= "UK" },

            new Country() { ID = 4, Name= "China" },

            new Country() { ID = 5, Name= "Japan" }

        };

    return new MultiSelectList(Countries, "ID", "Name", selectedValues);

}

public ActionResult MultiSelectCountry() {

    ViewBag.Countrieslist = GetCountries(null);

    return View();

}

El método GetCountries crea una lista de países y, a continuación, la pasa al constructor MultiSelectList. La sobrecarga de constructor MultiSelectList usada en el método GetCountries anterior toma cuatro parámetros:

public MultiSelectList(

    IEnumerable items,

    string dataValueField,

    string dataTextField,

    IEnumerable selectedValues

)
  1. Items: un objeto IEnumerable que contiene los elementos de la lista. En el ejemplo anterior, la lista de países.
  2. dataValueField: el nombre de la propiedad en la lista de IEnumerable que contiene el valor. En el ejemplo anterior, la propiedad ID.
  3. dataTextField: el nombre de la propiedad en la lista de IEnumerable que contiene la información que se mostrará. En el ejemplo anterior, la propiedad name.
  4. selectedValues: la lista de valores seleccionados.

En el ejemplo anterior, el método MultiSelectCountry pasa un valor null para los países seleccionados, por lo que no se selecciona ningún país cuando se muestra la interfaz de usuario. En el código siguiente se muestra el marcado de Razor que se usa para representar la vista MultiSelectCountry.

@{

    ViewBag.Title = "MultiSelect Country";

    Layout = "~/Views/Shared/_Simple_Layout.cshtml";

}

@if (ViewBag.YouSelected != null) {

    <div> You Selected:  @ViewBag.YouSelected</div>

}

@using (Html.BeginForm()) {

    <fieldset>

        <legend>Multi-Select Demo</legend>

        <div class="editor-field">

            @Html.ListBox("Countries", ViewBag.Countrieslist as MultiSelectList

            )

        </div>

        <p>

            <input type="submit" value="Save" />

        </p>

    </fieldset>

}

El método asistente de HTML ListBox usado anteriormente toma dos parámetros, el nombre de la propiedad para enlazar modelos y la MultiSelectList que contiene las opciones y los valores de selección. El código anterior ViewBag.YouSelected se usa para mostrar los valores de los países seleccionados al enviar el formulario. Examine la sobrecarga HTTP POST del método MultiSelectCountry.

[HttpPost]

public ActionResult MultiSelectCountry(FormCollection form) {

    ViewBag.YouSelected = form["Countries"];

    string selectedValues = form["Countries"];

    ViewBag.Countrieslist = GetCountries(selectedValues.Split(','));

    return View();

}

La propiedad dinámica ViewBag.YouSelected contiene los países seleccionados, obtenidos para la entrada Countries en la colección de formularios. En esta versión, al método GetCountries se le pasa a una lista de los países seleccionados, por lo que cuando se muestra la vista MultiSelectCountry, los países seleccionados se seleccionan en la interfaz de usuario.

Hacer que un elemento de selección sea amigable con el complemento Harvest Chosen jQuery

El complemento Harvest Chosen jQuery se puede agregar a un elemento de <selección> HTML para crear una interfaz de usuario fácil de usar. Las imágenes siguientes muestran el complemento Harvest Chosen jQuery con la vista MultiSelectCountry.

Image of Harvest Chosen j Query plugin

En las dos imágenes siguientes, se selecciona Canadá.

Image of Canada selected

Image of Canada selected with X to remove

En la imagen anterior, Canadá está seleccionado y contiene un elemento x que se puede clicar para quitar la selección. En la imagen siguiente se muestran Canadá, China y Japón seleccionados.

Image of Canada China and Japan selected

Enlazar el complemento Harvest Chosen jQuery

La siguiente sección es más fácil de seguir si tiene alguna experiencia con jQuery. Si nunca ha usado jQuery antes, es posible que quiera probar uno de los siguientes tutoriales de jQuery.

El complemento Chosen se incluye en los proyectos de ejemplo completados y de inicio que acompañan a este tutorial. En este tutorial, solo tendrá que usar jQuery para enlazarlo a la interfaz de usuario. Para usar el complemento Harvest Chosen jQuery en un proyecto de ASP.NET MVC, se necesita:

  1. Descargue el complemento Chosen de github. Este paso se ha realizado para usted.
  2. Agregue la carpeta Chosen al proyecto de ASP.NET MVC. Agregue los recursos del complemento Chosen que descargó en el paso anterior a la carpeta elegida. Este paso se ha realizado para usted.
  3. Conecte el complemento Chosen al asistente de HTML DropDownList o ListBox.

Enlazar el complemento Chosen a la vista MultiSelectCountry.

Abra el archivo Views\Home\MultiSelectCountry.cshtml y agregue un parámetro htmlAttributes a Html.ListBox. El parámetro que agregará contiene un nombre de clase para la lista de selección(@class = "chzn-select"). A continuación, se muestra el código completado:

<div class="editor-field">

    @Html.ListBox("Countries", ViewBag.Countrieslist as MultiSelectList

     , new

     {

         @class = "chzn-select",

         data_placeholder = "Choose  Countries..."

     }

    )

</div>

En el código anterior, agregaremos el atributo HTML y el valor de atributo class = "chzn-select". El carácter @ que precede a la clase no tiene nada que ver con el motor de vista de Razor. class es una palabra clave de C#. Las palabras clave de C# no se pueden usar como identificadores a menos que incluyan @ como prefijo. En el ejemplo anterior, @class es un identificador válido, pero class no lo es porque class es una palabra clave.

Agregue referencias a los archivos Chosen/chosen.jquery.js y Chosen/chosen.css. El Chosen/chosen.jquery.js e implementa la funcionalidad del complemento elegido. El archivo Chosen/chosen.css proporciona el estilo. Agregue estas referencias a la parte inferior del archivo Views\Home\MultiSelectCountry.cshtml. En el código siguiente se muestra cómo hacer referencia al complemento Chosen.

<script src="@Url.Content("~/Chosen/chosen.jquery.js")" type="text/javascript"></script><script src="@Url.Content("~/Chosen/chosen.jquery.js")" type="text/javascript"></script>

<link href="@Url.Content("~/Chosen/chosen.css")" rel="stylesheet"  type="text/css" />

Active el complemento Chosen con el nombre de clase usado en el código Html.ListBox. En el ejemplo anterior, el nombre de clase es chzn-select. Agregue la siguiente línea a la parte inferior del archivo de vista Views\Home\MultiSelectCountry.cshtml. Esta línea activa el complemento Chosen.

<script >    $(".chzn-select").chosen(); </script>  @*Hookup Chosen Plugin*@

La siguiente línea es la sintaxis para llamar a la función lista de jQuery, que selecciona el elemento DOM con el nombre de clase chzn-select.

$(".chzn-select")

El conjunto encapsulado devuelto desde la llamada anterior aplica el método elegido (.chosen();), que se enlaza al complemento Chosen.

El código siguiente muestra el archivo de vista Views\Home\MultiSelectCountry.cshtml completado.

@{

    ViewBag.Title = "MultiSelect Country";

    Layout = "~/Views/Shared/_Simple_Layout.cshtml";

}

@if (ViewBag.YouSelected != null) {

    <div> You Selected:  @ViewBag.YouSelected</div>

}

@using (Html.BeginForm()) {

    <fieldset>

        <legend>Multi-Select Demo</legend>

<div class="editor-field">

    @Html.ListBox("Countries", ViewBag.Countrieslist as MultiSelectList

     , new

     {

         @class = "chzn-select"

     }

    )

</div>

        <p>

            <input type="submit" value="Save" />

        </p>

    </fieldset>

}

<script src="@Url.Content("~/Chosen/chosen.jquery.js")" type="text/javascript"></script>

<link href="@Url.Content("~/Chosen/chosen.css")" rel="stylesheet"  type="text/css" />

<script >    $(".chzn-select").chosen(); </script> @*Hookup Chosen Plugin*@

Ejecute la aplicación y vaya a la vista MultiSelectCountry. Intente agregar y eliminar países. La descarga de ejemplo proporcionada también contiene un método MultiCountryVM y una vista que implementa la funcionalidad MultiSelectCountry mediante un modelo de vista en lugar de ViewBag.

En la sección siguiente, verá cómo funciona el mecanismo de andamiaje de ASP.NET MVC con el asistente DropDownList.