Compartir a través de


Formato personalizado basado en datos (C#)

por Scott Mitchell

Descargar PDF

Ajustar el formato de GridView, DetailsView o FormView en función de los datos enlazados a él se puede lograr de varias maneras. En este tutorial veremos cómo realizar el formato enlazado a datos mediante el uso de los controladores de eventos DataBound y RowDataBound.

Introducción

La apariencia de los controles GridView, DetailsView y FormView se puede personalizar a través de una gran cantidad de propiedades relacionadas con el estilo. Las propiedades como CssClass, Font, BorderWidth, BorderStyle, BorderColor, Width y Height, entre otras, dictan la apariencia general del control representado. Las propiedades que incluyen HeaderStyle, RowStyle, AlternatingRowStyle, así como otras, permiten aplicar estas mismas opciones de estilo a secciones concretas. Del mismo modo, esta configuración de estilo se puede aplicar en el nivel de campo.

Sin embargo, en muchos escenarios, los requisitos de formato dependen del valor de los datos mostrados. Por ejemplo, para informar sobre los productos agotados, un informe que enumera la información de producto podría establecer el color de fondo en amarillo en aquellos productos cuyos campos UnitsInStock y UnitsOnOrder son iguales a 0. Para resaltar los productos más caros, es posible que deseemos mostrar los precios de esos productos que cuestan más de 75 $ en una fuente negrita.

Ajustar el formato de GridView, DetailsView o FormView en función de los datos enlazados a él se puede lograr de varias maneras. En este tutorial veremos cómo lograr el formato enlazado a datos con el uso de los controladores de eventos DataBound y RowDataBound. En el siguiente tutorial exploraremos un enfoque alternativo.

Uso del controlador de eventos DataBound del control DetailsView

Al enlazar los datos a DetailsView, ya sea desde un control de origen de datos o la asignación mediante programación de datos a la propiedad DataSource del control y la llamada a su método DataBind(), se produce la siguiente secuencia de pasos:

  1. El evento DataBinding del control de web de datos se activa.
  2. Los datos se enlazan al control web de datos.
  3. El evento DataBound del control de web de datos se activa.

Se puede insertar la lógica personalizada inmediatamente después de los pasos 1 y 3 con un controlador de eventos. Al crear un controlador de eventos para el evento DataBound, podemos determinar mediante programación los datos que se han enlazado al control web de datos y ajustar el formato según sea necesario. Para ilustrar esto, crearemos un DetailsView que muestre información general sobre un producto, pero mostrará el valor UnitPrice en negrita y cursiva si vale más de 75 $.

Paso 1: Mostrar la información del producto en un DetailsView

Abre la página CustomColors.aspx de la carpeta CustomFormatting, arrastra un control DetailsView desde el Cuadro de herramientas al Diseñador, establece su valor de propiedad ID en ExpensiveProductsPriceInBoldItalic y vincúlalo a un nuevo control ObjectDataSource que invoca al método GetProducts() de la clase ProductsBLL. Los pasos detallados de este proceso se omiten para una mayor brevedad, ya que se examinaron con detalle en tutoriales anteriores.

Una vez que hayas enlazado ObjectDataSource a DetailsView, modifica la lista de campos. He optado por quitar los BoundFields ProductID, SupplierID, CategoryID, UnitsInStock, UnitsOnOrder, ReorderLevel y Discontinued, así como por cambiar el nombre y formato de los BoundFields restantes. También he eliminado las configuraciones Width y Height. Dado que DetailsView solo muestra un único registro, es necesario habilitar la paginación para permitir que el usuario final vea todos los productos. Para ello, marca la casilla Habilitar paginación en la etiqueta inteligente de DetailsView.

Check the Enable Paging Checkbox in the DetailsView's Smart Tag

Figura 1: Marca la casilla Habilitar paginación en la etiqueta inteligente de DetailsView (haz clic para ver la imagen en tamaño completo)

Después de estos cambios, el marcado DetailsView será:

<asp:DetailsView ID="DetailsView1" runat="server" AllowPaging="True"
    AutoGenerateRows="False" DataKeyNames="ProductID"
    DataSourceID="ObjectDataSource1" EnableViewState="False">
    <Fields>
        <asp:BoundField DataField="ProductName" HeaderText="Product"
          SortExpression="ProductName" />
        <asp:BoundField DataField="CategoryName" HeaderText="Category"
          ReadOnly="True" SortExpression="CategoryName" />
        <asp:BoundField DataField="SupplierName" HeaderText="Supplier"
          ReadOnly="True" SortExpression="SupplierName" />
        <asp:BoundField DataField="QuantityPerUnit"
          HeaderText="Qty/Unit" SortExpression="QuantityPerUnit" />
        <asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}"
          HeaderText="Price"
            HtmlEncode="False" SortExpression="UnitPrice" />
    </Fields>
</asp:DetailsView>

Dedica un momento a probar esta página en el explorador.

The DetailsView Control Displays One Product at a Time

Figura 2: El control DetailsView muestra un producto a la vez (haz clic para ver la imagen a tamaño completo)

Paso 2: Determinar mediante programación el valor de los datos en el controlador de eventos DataBound

Es necesario poder determinar el valor UnitPrice mediante programación para mostrar el precio en negrita y cursiva de los productos cuyo valor UnitPrice sea superior a 75 $. En DetailsView, esto puede hacerse con el controlador de eventos DataBound. Para crear el controlador de eventos, haz clic en DetailsView en el Diseñador y, a continuación, ve a la ventana Propiedades. Pulsa F4 para abrirlo si no está visible, o ve al menú Ver y selecciona la opción ventana Propiedades del menú. En la ventana Propiedades, haz clic en el icono de rayo para enumerar los eventos de DetailsView. A continuación, haz doble clic en el evento DataBound o escribe el nombre del controlador de eventos que quieres crear.

Create an Event Handler for the DataBound Event

Figura 3: Crear un controlador de eventos para el evento DataBound

Al hacerlo, se creará automáticamente el controlador de eventos y te llevará a la parte de código donde se ha agregado. En este momento verás lo siguiente:

protected void ExpensiveProductsPriceInBoldItalic_DataBound(object sender, EventArgs e)
{

}

Se puede acceder a los datos enlazados a DetailsView mediante la propiedad DataItem. Recuerda que estamos enlazando los controles a una DataTable fuertemente tipada, compuesta por una colección de instancias de DataRow fuertemente tipadas. Cuando DataTable está enlazada a DetailsView, el primer DataRow en DataTable se asigna a la propiedad DataItem de DetailsView. En concreto, a la propiedad DataItem se le asigna un objeto DataRowView. Podemos usar la propiedad Row de DataRowView para obtener acceso al objeto DataRow subyacente, que en realidad es una instancia ProductsRow. Una vez que tengamos esta instancia ProductsRow, podemos tomar la decisión con solo inspeccionar los valores de propiedad del objeto.

El siguiente código muestra cómo determinar si el valor UnitPrice enlazado al control DetailsView es mayor que 75 $:

protected void ExpensiveProductsPriceInBoldItalic_DataBound(object sender, EventArgs e)
{
    // Get the ProductsRow object from the DataItem property...
    Northwind.ProductsRow product = (Northwind.ProductsRow)
        ((DataRowView)ExpensiveProductsPriceInBoldItalic.DataItem).Row;
    if (!product.IsUnitPriceNull() && product.UnitPrice > 75m)
    {
        // TODO: Make the UnitPrice text bold and italic
    }
}

Nota:

Como UnitPrice puede tener un valor NULL en la base de datos, primero comprobamos que no estamos tratando con un valor NULL antes de acceder a la propiedad UnitPrice de ProductsRow. Esta comprobación es importante porque si intentamos acceder a la propiedad UnitPrice cuando tiene un valor NULL, el objeto ProductsRow producirá una excepción StrongTypingException.

Paso 3: Aplicar formato al valor UnitPrice en DetailsView

Llegados a este punto podemos determinar si el valor UnitPrice enlazado a DetailsView tiene un valor mayor a 75 $, pero todavía tenemos que ver cómo ajustar adecuadamente mediante programación el formato de DetailsView. Para modificar el formato de una fila completa en DetailsView, accede mediante programación a la fila con DetailsViewID.Rows[index]. Para modificar una celda concreta, accede utilizando DetailsViewID.Rows[index].Cells[index]. Cuando tengamos una referencia a la fila o celda, podemos ajustar su apariencia al establecer sus propiedades relacionadas con el estilo.

El acceso a una fila mediante programación requiere que conozcas el índice de la fila, que comienza en 0. La fila UnitPrice es la quinta de DetailsView, lo que resulta en un índice de 4 y hace que sea accesible mediante programación con ExpensiveProductsPriceInBoldItalic.Rows[4]. En este momento, podríamos tener el contenido de toda la fila mostrado en negrita y cursiva con el siguiente código:

ExpensiveProductsPriceInBoldItalic.Rows[4].Font.Bold = true;
ExpensiveProductsPriceInBoldItalic.Rows[4].Font.Italic = true;

Sin embargo, esto hará que ambas, la etiqueta (precio) y el valor estén en negrita y cursiva. Si queremos poner solo el valor en negrita y cursiva, es necesario aplicar este formato a la segunda celda de la fila, haciendo lo siguiente:

ExpensiveProductsPriceInBoldItalic.Rows[4].Cells[1].Font.Bold = true;
ExpensiveProductsPriceInBoldItalic.Rows[4].Cells[1].Font.Italic = true;

Dado que nuestros tutoriales hasta ahora han usado hojas de estilos para separar claramente el marcado representado y la información relacionada con el estilo, en vez de establecer las propiedades de estilo específicas como se muestra anteriormente, vamos a usar, en su lugar, una clase CSS. Abre la hoja de estilos Styles.css y agrega una nueva clase CSS con el nombre ExpensivePriceEmphasis y la siguiente definición:

.ExpensivePriceEmphasis
{
    font-weight: bold;
    font-style: italic;
}

Luego, en el controlador de eventos DataBound, establece la propiedad CssClass de la celda en ExpensivePriceEmphasis. El siguiente código muestra completamente el controlador de eventos DataBound.

protected void ExpensiveProductsPriceInBoldItalic_DataBound(object sender, EventArgs e)
{
    // Get the ProductsRow object from the DataItem property...
    Northwind.ProductsRow product = (Northwind.ProductsRow)
        ((DataRowView)ExpensiveProductsPriceInBoldItalic.DataItem).Row;
    if (!product.IsUnitPriceNull() && product.UnitPrice > 75m)
    {
        ExpensiveProductsPriceInBoldItalic.Rows[4].Cells[1].CssClass =
            "ExpensivePriceEmphasis";
    }
}

Al ver el producto Chai, que cuesta menos de 75 $, el precio se muestra en una fuente normal (véase la captura 4). Sin embargo, al ver el producto Mishi Kobe Niku, que cuesta 97 $, el precio se muestra en negrita y cursiva (véase la captura 5).

Prices Less than $75.00 are Displayed in a Normal Font

Figura 4: Los precios inferiores a 75 $ se muestran en una fuente normal (haz clic para ver la imagen a tamaño completo)

Expensive Products' Prices are Displayed in a Bold, Italic Font

Figura 5: Los precios de los productos caros se muestran en negrita y cursiva (haz clic para ver la imagen a tamaño completo)

Uso del controlador de eventos DataBound del control FormView

Los pasos para determinar los datos subyacentes enlazados a un FormView son iguales a los de DetailsView. Para crear un controlador de eventos DataBound, convierte la propiedad DataItem en el tipo de objeto adecuado enlazado al control y determina cómo continuar. FormView y DetailsView difieren, sin embargo, en la forma en que se actualiza la apariencia de la interfaz de usuario.

FormView no contiene ningún BoundFields y, por tanto, carece de la colección Rows. En su lugar, FormView está formado por plantillas, que pueden contener una combinación de HTML estático, controles web y sintaxis de enlace de datos. Ajustar el estilo de un FormView suele implicar ajustar el estilo de uno o varios de los controles web dentro de las plantillas de FormView.

Para ilustrar esto, vamos a usar un FormView que enumere productos como en el ejemplo anterior, pero esta vez se mostrará solo el nombre del producto y unidades en stock con las unidades de stock en una fuente roja si es menor o igual que 10.

Paso 4: Mostrar la información del producto en un FormView

Agrega un FormView a la página CustomColors.aspx debajo de DetailsView y establece su propiedad ID en LowStockedProductsInRed. Enlaza FormView al control ObjectDataSource creado a partir del paso anterior. Esto creará un ItemTemplate, EditItemTemplate y InsertItemTemplate en FormView. Quita EditItemTemplate y InsertItemTemplate simplifica ItemTemplate para incluir solo los valores ProductName y UnitsInStock, cada uno de ellos con sus propios controles de etiqueta adecuadamente nombrados. Al igual que con DetailsView del ejemplo anterior, marca también la casilla Habilitar paginación en la etiqueta inteligente de FormView.

Después de estas modificaciones, el marcado de FormView debe ser similar al siguiente:

<asp:FormView ID="LowStockedProductsInRed" DataKeyNames="ProductID"
    DataSourceID="ObjectDataSource1" AllowPaging="True"
    EnableViewState="False" runat="server">
    <ItemTemplate>
        <b>Product:</b>
        <asp:Label ID="ProductNameLabel" runat="server"
         Text='<%# Bind("ProductName") %>'>
        </asp:Label><br />
        <b>Units In Stock:</b>
        <asp:Label ID="UnitsInStockLabel" runat="server"
          Text='<%# Bind("UnitsInStock") %>'>
        </asp:Label>
    </ItemTemplate>
</asp:FormView>

Ten en cuenta que ItemTemplate contiene:

  • HTML estático: el texto "Producto:" y "Unidades en Stock:", junto con los elementos <br /> y <b>.
  • Controles web: los dos controles de etiqueta, ProductNameLabel y UnitsInStockLabel.
  • Sintaxis de enlace de datos: las sintaxis <%# Bind("ProductName") %> y <%# Bind("UnitsInStock") %>, que asignan los valores de estos campos a las propiedades Text de los controles de etiqueta.

Paso 5: Determinar mediante programación el valor de los datos en el controlador de eventos DataBound

Con el marcado de FormView terminado, el siguiente paso es determinar mediante programación si el valor UnitsInStock es menor o igual que 10. Esto se logra de la misma manera con FormView, tal y como se hizo con DetailsView. Empieza por crear un controlador de eventos para el evento DataBound de FormView.

Create the DataBound Event Handler

Figura 6: Crear el controlador de eventos DataBound

En el controlador de eventos, convierte la propiedad DataItem de FormView en una instancia ProductsRow y determina si el valor UnitsInPrice es el que necesitamos para mostrarlo en una fuente roja.

protected void LowStockedProductsInRed_DataBound(object sender, EventArgs e)
{
    // Get the ProductsRow object from the DataItem property...
    Northwind.ProductsRow product = (Northwind.ProductsRow)
        ((DataRowView)LowStockedProductsInRed.DataItem).Row;
    if (!product.IsUnitsInStockNull() && product.UnitsInStock <= 10)
    {
        // TODO: Make the UnitsInStockLabel text red
    }
}

Paso 6: Aplicar formato al control de etiqueta UnitsInStockLabel en ItemTemplate de FormView

El último paso consiste en formatear el valor UnitsInStock para que se muestre en una fuente roja si es 10 o menos. Para ello, es necesario acceder mediante programación al control UnitsInStockLabel en ItemTemplate y establecer sus propiedades de estilo para que su texto se muestre en rojo. Para acceder a un control web de una plantilla, usa el método FindControl("controlID") de la siguiente manera:

WebControlType someName = (WebControlType)FormViewID.FindControl("controlID");

En nuestro ejemplo, queremos acceder a un control de etiqueta cuyo valor ID es UnitsInStockLabel, por lo que usaríamos:

Label unitsInStock =
    (Label)LowStockedProductsInRed.FindControl("UnitsInStockLabel");

Una vez que tengamos una referencia mediante programación al control Web, podemos modificar sus propiedades relacionadas con el estilo según sea necesario. Al igual que con el ejemplo anterior, se ha creado una clase CSS en Styles.css con el nombre LowUnitsInStockEmphasis. Para aplicar este estilo al control web de etiqueta, establece su propiedad CssClass en consecuencia.

protected void LowStockedProductsInRed_DataBound(object sender, EventArgs e)
{
    // Get the ProductsRow object from the DataItem property...
    Northwind.ProductsRow product = (Northwind.ProductsRow)
        ((DataRowView)LowStockedProductsInRed.DataItem).Row;
    if (!product.IsUnitsInStockNull() && product.UnitsInStock <= 10)
    {
        Label unitsInStock =
            (Label)LowStockedProductsInRed.FindControl("UnitsInStockLabel");

        if (unitsInStock != null)
        {
          unitsInStock.CssClass = "LowUnitsInStockEmphasis";
        }
    }
}

Nota:

La sintaxis para dar formato a una plantilla accediendo mediante programación al control Web con FindControl("controlID") y establecer sus propiedades relacionadas con el estilo también se puede usar al utilizar TemplateFields en los controles DetailsView o GridView. TemplateFields se examinará en el siguiente tutorial.

La figura 7 muestra FormView al ver un producto cuyo valor UnitsInStock es mayor que 10, mientras que el producto de la figura 8 tiene un valor inferior a 10.

For Products With a Sufficiently Large Units In Stock, No Custom Formatting is Applied

Figura 7: no se aplica ningún formato personalizado en los productos con unidades suficientes en stock, (haz clic para ver la imagen a tamaño completo)

The Units in Stock Number is Shown in Red for Those Products With Values of 10 or Less

Figura 8: el número de unidades en stock de los productos con valores de 10 o menos está en rojo (haz clic para ver la imagen a tamaño completo)

Dar formato con el evento RowDataBound de GridView

Anteriormente hemos examinado la secuencia de pasos que siguen los controles DetailsView y FormView durante el enlace de datos. Echemos un vistazo a estos pasos una vez más para repasarlo.

  1. El evento DataBinding del control de web de datos se activa.
  2. Los datos se enlazan al control web de datos.
  3. El evento DataBound del control de web de datos se activa.

Estos tres sencillos pasos son suficientes para DetailsView y FormView porque solo muestran un único registro. Para GridView, que muestra todos los registros que tiene enlazados (no solo el primero), el paso 2 es un poco más complicado.

En el paso 2, GridView enumera el origen de datos y, para cada registro, crea una instancia GridViewRow y enlaza el registro actual a él. Para cada GridViewRow agregado a GridView, se generan dos eventos:

  • RowCreated se desencadena después de que se haya creado GridViewRow.
  • RowDataBound se desencadena después de que el registro actual se haya enlazado a GridViewRow.

Para GridView, por tanto, el enlace de datos se describe con más precisión mediante la siguiente secuencia de pasos:

  1. Se desencadena el evento DataBinding de GridView.

  2. Los datos se enlazan a GridView.

    Para cada registro del origen de datos:

    1. Crea un objeto GridViewRow.
    2. Desencadena el evento RowCreated
    3. Enlaza el registro a GridViewRow.
    4. Desencadena el evento RowDataBound
    5. Agrega GridViewRow a la colección Rows.
  3. Se desencadena el evento DataBound de GridView.

Para personalizar el formato de los registros individuales de GridView, es necesario crear un controlador de eventos para el evento RowDataBound. Para ilustrar esto, agreguemos un GridView a la página CustomColors.aspx que muestra el nombre, la categoría y el precio de cada producto, y resalta aquellos cuyo precio es menor que 10 € con un color de fondo amarillo.

Paso 7: Mostrar información del producto en un GridView

Agrega un GridView debajo del FormView del ejemplo anterior y establece su propiedad ID en HighlightCheapProducts. Puesto que ya tenemos un ObjectDataSource que devuelve todos los productos de la página, enlaza GridView a él. Por último, edita los BoundFields de GridView para incluir solo los nombres, las categorías y los precios de los productos. Tras estos cambios, el marcado de GridView debe ser similar al siguiente:

<asp:GridView ID="HighlightCheapProducts" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1"
    EnableViewState="False" runat="server">
    <Columns>
        <asp:BoundField DataField="ProductName" HeaderText="Product"
          SortExpression="ProductName" />
        <asp:BoundField DataField="CategoryName" HeaderText="Category"
          ReadOnly="True" SortExpression="CategoryName" />
        <asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}"
          HeaderText="Price"
            HtmlEncode="False" SortExpression="UnitPrice" />
    </Columns>
</asp:GridView>

En la figura 9 se muestra el progreso hasta ahora visto desde un explorador.

The GridView Lists the Name, Category, and Price For Each Product

Figura 9: GridView enumera el nombre, la categoría y el precio de cada producto (haz clic para ver la imagen a tamaño completo)

Paso 8: Determinar mediante programación el valor de los datos en el controlador de eventos RowDataBound

Cuando ProductsDataTable está enlazado a GridView, sus instancias ProductsRow se enumeran y se crea un GridViewRow para cada ProductsRow. La propiedad GridViewRow de DataItem se asigna al ProductRow determinado, del cual después se genera el controlador de eventos RowDataBound de GridView. Para determinar el valor UnitPrice de cada producto enlazado a GridView, es necesario crear un controlador de eventos para el evento RowDataBound de GridView. En este controlador de eventos, podemos inspeccionar el valor UnitPrice del actual GridViewRow y tomar una decisión del formato de esa fila.

Este controlador de eventos se puede crear con los mismos pasos que con FormView y DetailsView.

Create an Event Handler for the GridView's RowDataBound Event

Figura 10: Crear un controlador de eventos para el evento RowDataBound de GridView

Crear el controlador de eventos de esta manera hará que el siguiente código se agregue automáticamente a la parte de código de la página de ASP.NET:

protected void HighlightCheapProducts_RowDataBound(object sender, GridViewRowEventArgs e)
{

}

Cuando se desencadena el evento RowDataBound, el controlador de eventos se pasa como segundo parámetro un objeto de tipo GridViewRowEventArgs, que tiene una propiedad con el nombre Row. Esta propiedad devuelve una referencia al GridViewRow que solo estaba enlazado a datos. Para acceder a la instancia ProductsRow enlazada a GridViewRow, usamos la propiedad DataItem de la siguiente manera:

protected void HighlightCheapProducts_RowDataBound(object sender, GridViewRowEventArgs e)
{
    // Get the ProductsRow object from the DataItem property...
    Northwind.ProductsRow product = (Northwind.ProductsRow)
        ((System.Data.DataRowView)e.Row.DataItem).Row;
    if (!product.IsUnitPriceNull() && product.UnitPrice < 10m)
    {
        // TODO: Highlight the row yellow...
    }
}

Al trabajar con el controlador de eventos RowDataBound, es importante tener en cuenta que GridView se compone de diferentes tipos de filas y que este evento se desencadena para todos los tipos de fila. La propiedad RowType de un GridViewRow puede determinar su tipo, que puede tener unos de los siguientes valores posibles:

  • DataRow: una fila enlazada a un registro del DataSource de GridView.
  • EmptyDataRow: la fila que se muestra si el control DataSource de GridView está vacío.
  • Footer: la fila de pie de página. Se muestra si la propiedad ShowFooter de GridView está establecida en true.
  • Header: la fila de encabezado. Se muestra si la propiedad ShowHeader de GridView está establecida en true (el valor predeterminado).
  • Pager: para GridView que implementa la paginación, la fila que muestra la interfaz de paginación.
  • Separator: no se usa para GridView, sino para las propiedades RowType de los controles DataList y Repeater, se analizarán dos controles web de datos en los próximos tutoriales.

Dado que las filas EmptyDataRow, Header, Footer y Pager no están asociadas a un registro DataSource, siempre tendrán un valor null en su propiedad DataItem. Por esto, antes de intentar trabajar con la propiedad actual DataItem de GridViewRow, primero debemos asegurarnos de que estamos tratando con un DataRow. Esto se puede lograr comprobando la propiedad RowType de GridViewRow de la siguiente manera:

protected void HighlightCheapProducts_RowDataBound(object sender, GridViewRowEventArgs e)
{
    // Make sure we are working with a DataRow
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        // Get the ProductsRow object from the DataItem property...
        Northwind.ProductsRow product = (Northwind.ProductsRow)
            ((System.Data.DataRowView)e.Row.DataItem).Row;
        if (!product.IsUnitPriceNull() && product.UnitPrice < 10m)
        {
          // TODO: Highlight row yellow...
        }
    }
}

Paso 9: Resaltar la fila amarilla cuando el valor UnitPrice es menor que 10 $

El último paso consiste en resaltar mediante programación todo el GridViewRow si el valor UnitPrice de esa fila es inferior a 10 $. La sintaxis para acceder a las filas o celdas de GridView es la misma que con GridViewID.Rows[index] de DetailsView para acceder a toda la fila, y conGridViewID.Rows[index].Cells[index] para acceder a una celda determinada. Sin embargo, cuando el controlador de eventos RowDataBound activa el enlazador de datos, GridViewRow aún no se ha agregado a la colección Rows de GridView. Por lo tanto, no puedes acceder a la instancia GridViewRow actual desde el controlador de eventos RowDataBound mediante la colección Rows.

En lugar de GridViewID.Rows[index], podemos hacer referencia a la instancia GridViewRow actual en el controlador de eventos RowDataBound con e.Row. Es decir, para resaltar la instancia GridViewRow actual del controlador de eventos RowDataBound, usaríamos:

e.Row.BackColor = System.Drawing.Color.Yellow;

En vez de establecer la propiedad BackColor de GridViewRow directamente, vamos a usar clases CSS. Hemos creado una clase CSS con el nombre AffordablePriceEmphasis que establece el color de fondo en amarillo. El controlador de eventos RowDataBound completo es así:

protected void HighlightCheapProducts_RowDataBound(object sender, GridViewRowEventArgs e)
{
    // Make sure we are working with a DataRow
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        // Get the ProductsRow object from the DataItem property...
        Northwind.ProductsRow product = (Northwind.ProductsRow)
            ((System.Data.DataRowView)e.Row.DataItem).Row;
        if (!product.IsUnitPriceNull() && product.UnitPrice < 10m)
        {
            e.Row.CssClass = "AffordablePriceEmphasis";
        }
    }
}

The Most Affordable Products are Highlighted Yellow

Figura 11: Los productos más asequibles están resaltados en amarillo (haz clic para ver la imagen a tamaño completo)

Resumen

En este tutorial hemos visto cómo dar formato a GridView, DetailsView y FormView según los datos enlazados al control. Para ello, creamos un controlador de eventos para los eventos DataBound o RowDataBound, donde se examinaron los datos subyacentes junto con un cambio de formato, si era necesario. Para acceder a los datos enlazados a DetailsView o FormView, usamos la propiedad DataItem en el controlador de eventos DataBound. Para acceder a un GridView, la propiedad GridViewRow de cada instancia DataItem contiene los datos enlazados a esa fila, que está disponible en el controlador de eventos RowDataBound.

La sintaxis para ajustar mediante programación el formato del control web de datos depende del control web y de cómo se muestran los datos a los que se va a dar formato. Se puede acceder a las filas y celdas de DetailsView y GridView con un índice ordinal. En FormView, que usa plantillas, el método FindControl("controlID") se usa normalmente para buscar un control web desde dentro de la plantilla.

En el siguiente tutorial veremos cómo usar plantillas con GridView y DetailsView. Además, veremos otra técnica para personalizar el formato según los datos subyacentes.

¡Feliz programación!

Acerca del autor

Scott Mitchell, autor de siete libros de ASP/ASP.NET y fundador de 4GuysFromRolla.com, ha estado trabajando con tecnologías web de Microsoft desde 1998. Scott trabaja como consultor independiente, entrenador y escritor. Su último libro es Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Puedes ponerte en contacto con él en mitchell@4GuysFromRolla.com. o a través de su blog, http://ScottOnWriting.NET.

Agradecimientos especiales a

Esta serie de tutoriales fue revisada por muchos revisores que fueron de gran ayuda. Los revisores principales de este tutorial eran E.R. Gilmore, Dennis Patterson y Dan Jagers. ¿Te interesa revisar mis próximos artículos de MSDN? Si es así, escríbeme a mitchell@4GuysFromRolla.com.