Personalizar la interfaz de modificación de datos (VB)
por Scott Mitchell
En este tutorial, verá cómo personalizar la interfaz de un control GridView editable, y reemplazar los controles TextBox y CheckBox estándar por controles web de entrada alternativos.
Introducción
Los controles BoundField y CheckBoxField usados por los controles GridView y DetailsView simplifican el proceso de modificación de datos debido a su capacidad de representar interfaces de solo lectura, editable e insertables. Estas interfaces se pueden representar sin necesidad de agregar ningún código o marcado declarativo adicional. Pero las interfaces de BoundField y CheckBoxField carecen de la personalización que a menudo se necesita en escenarios reales. Para personalizar la interfaz editable o insertable en un control GridView o DetailsView, en su lugar es necesario usar una instancia de TemplateField.
En el tutorial anterior ha visto cómo personalizar las interfaces de modificación de datos mediante la adición de controles web de validación. En este tutorial, verá cómo personalizar los controles web de recopilación de datos reales y reemplazar los controles TextBox y CheckBoxField estándar de BoundField y CheckBox Con controles web de entrada alternativos. En concreto, creará un control GridView editable que permita actualizar el nombre, la categoría, el proveedor y el estado de un producto. Al editar una fila determinada, los campos de categoría y proveedor se representarán como controles DropDownList, que contienen el conjunto de categorías y proveedores disponibles entre los que elegir. Además, reemplazará el elemento CheckBox predeterminado de CheckBoxField por un control RadioButtonList que ofrece dos opciones: "Active" y "Discontinued".
Figura 1: La interfaz de edición de GridView incluye controles DropDownList y RadioButton (haga clic para ver la imagen a tamaño completo)
Paso 1: Creación de la sobrecarga de UpdateProduct
adecuada
En este tutorial, creará un control GridView editable que permita la edición del nombre, la categoría, el proveedor y el estado de un producto. Por tanto, necesita una sobrecarga de UpdateProduct
que acepte cinco parámetros de entrada estos: cuatro valores de producto más ProductID
. Como las sobrecargas anteriores, esta hará lo siguiente:
- Recuperar la información del producto de la base de datos para el objeto
ProductID
especificado, - Actualizar los campos
ProductName
,CategoryID
,SupplierID
yDiscontinued
, y - Enviar la solicitud de actualización a DAL por medio del método
Update()
de TableAdapter.
Por motivos de brevedad, para esta sobrecarga concreta se ha omitido la comprobación de la regla de negocio que garantiza que un producto que se marque como no disponible no sea el único producto ofrecido por su proveedor. No dude en agregarla si lo prefiere o, idealmente, refactorizar la lógica en un método independiente.
En el código siguiente se muestra la nueva sobrecarga de UpdateProduct
en la clase ProductsBLL
:
<System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, False)>
Public Function UpdateProduct(
ByVal productName As String, ByVal categoryID As Nullable(Of Integer),
ByVal supplierID As Nullable(Of Integer), ByVal discontinued As Boolean,
ByVal productID As Integer)
As Boolean
Dim products As Northwind.ProductsDataTable = Adapter.GetProductByProductID(productID)
If products.Count = 0 Then
Return False
End If
Dim product As Northwind.ProductsRow = products(0)
product.ProductName = productName
If Not supplierID.HasValue Then
product.SetSupplierIDNull()
Else
product.SupplierID = supplierID.Value
End If
If Not categoryID.HasValue Then
product.SetCategoryIDNull()
Else
product.CategoryID = categoryID.Value
End If
product.Discontinued = discontinued
Dim rowsAffected As Integer = Adapter.Update(product)
Return rowsAffected = 1
End Function
Paso 2: Creación del control GridView editable
Después de agregar la sobrecarga de UpdateProduct
, ya puede crear el control GridView editable. Abra la página CustomizedUI.aspx
en la carpeta EditInsertDelete
y agregue un control GridView al Diseñador. A continuación, cree una instancia de ObjectDataSource desde la etiqueta inteligente de GridView. Configure ObjectDataSource para recuperar información del producto con el método GetProducts()
de la clase ProductBLL
y para actualizar los datos del producto mediante la sobrecarga de UpdateProduct
que acaba de crear. En las pestañas INSERT y DELETE, seleccione (Ninguno) en las listas desplegables.
Figura 2: Configuración de ObjectDataSource para usar la sobrecarga de UpdateProduct
que se acaba de crear (haga clic para ver la imagen a tamaño completo)
Como ha visto en los tutoriales de modificación de datos, la sintaxis declarativa de ObjectDataSource creada por Visual Studio asigna la propiedad OldValuesParameterFormatString
a original_{0}
. Esto, por supuesto, no funcionará con la capa de lógica de negocios, ya que los métodos no esperan que se pase el valor ProductID
original. Por tanto, como ha hecho en los tutoriales anteriores, dedique un momento a quitar esta asignación de propiedad de la sintaxis declarativa o, en su lugar, establezca el valor de esta propiedad en {0}
.
Después de este cambio, el marcado declarativo de ObjectDataSource debe ser similar al siguiente:
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
SelectMethod="GetProducts" TypeName="ProductsBLL"
UpdateMethod="UpdateProduct">
<UpdateParameters>
<asp:Parameter Name="productName" Type="String" />
<asp:Parameter Name="categoryID" Type="Int32" />
<asp:Parameter Name="supplierID" Type="Int32" />
<asp:Parameter Name="discontinued" Type="Boolean" />
<asp:Parameter Name="productID" Type="Int32" />
</UpdateParameters>
</asp:ObjectDataSource>
Observe que la propiedad OldValuesParameterFormatString
se ha quitado y que hay un elemento Parameter
en la colección UpdateParameters
para cada uno de los parámetros de entrada que espera la sobrecarga de UpdateProduct
.
Aunque ObjectDataSource está configurado para actualizar solo un subconjunto de valores de producto, en GridView se muestran actualmente todos los campos del producto. Dedique un momento a editar GridView para que:
- Solo incluya las instancias de BoundField
ProductName
,SupplierName
yCategoryName
, y el control CheckBoxFieldDiscontinued
- Los campos
CategoryName
ySupplierName
aparezcan antes que (a la izquierda) el control CheckBoxFieldDiscontinued
- La
HeaderText
de los controles BoundFieldCategoryName
ySupplierName
se establezca en "Category" y "Supplier", respectivamente - La compatibilidad con la edición está habilitada (active la casilla Habilitar edición en la etiqueta inteligente de GridView)
Después de estos cambios, el Diseñador tendrá un aspecto similar al de la figura 3, con la sintaxis declarativa de GridView que se muestra a continuación.
Figura 3: Eliminación de los campos innecesarios de GridView (haga clic para ver la imagen a tamaño completo)
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
<Columns>
<asp:BoundField DataField="ProductName"
HeaderText="ProductName" SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName" HeaderText="Category"
ReadOnly="True"
SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName" HeaderText="Supplier"
ReadOnly="True"
SortExpression="SupplierName" />
<asp:CheckBoxField DataField="Discontinued"
HeaderText="Discontinued" SortExpression="Discontinued" />
</Columns>
</asp:GridView>
En este momento, el comportamiento de solo lectura de GridView está completo. Al ver los datos, cada producto se representa como una fila en el control GridView, y muestra el nombre del producto, la categoría, el proveedor y el estado interrumpido.
Figura 4: La interfaz de solo lectura de GridView está completa (haga clic para ver la imagen a tamaño completo)
Nota:
Como se describe en el tutorial Introducción a la inserción, actualización y eliminación de datos, es fundamental que el estado de visualización de GridView esté habilitado (el comportamiento predeterminado). Si establece la propiedad EnableViewState
de GridView en false
, corre el riesgo de que los usuarios simultáneos eliminen o editen registros accidentalmente.
Paso 3: Uso de una lista desplegable para las interfaces de edición de categoría y proveedor
Recuerde que el objeto ProductsRow
contiene las propiedades CategoryID
, CategoryName
, SupplierID
y SupplierName
, que proporcionan los valores reales de identificador de clave externa en la tabla de base de datos Products
y los valores Name
correspondientes de las tablas Categories
y Suppliers
. CategoryID
y SupplierID
de ProductRow
se pueden leer desde y escribir en ellos, mientras que las propiedades CategoryName
y SupplierName
están marcadas como de solo lectura.
Debido al estado de solo lectura de las propiedades CategoryName
y SupplierName
, en los controles BoundField correspondientes se ha establecido la propiedad ReadOnly
enTrue
, lo que impide que estos valores se modifiquen al editar una fila. Aunque se puede establecer la propiedad ReadOnly
en False
, y representar los controles BoundField CategoryName
y SupplierName
como controles TextBox durante la edición, este enfoque iniciaría una excepción cuando el usuario intente actualizar el producto, ya que no hay ninguna sobrecarga de UpdateProduct
que tome entradas CategoryName
y SupplierName
. De hecho, no querrá crear esta sobrecarga por dos motivos:
- La tabla
Products
no tiene camposSupplierName
niCategoryName
, pero síSupplierID
yCategoryID
. Por tanto, quiere que al método se le pasen estos valores de identificador concretos, no sus valores de las tablas de búsqueda. - Exigir al usuario que escriba el nombre del proveedor o categoría no es lo ideal, ya que requiere que el usuario conozca las categorías y proveedores disponibles y su ortografía correcta.
Los campos de proveedor y categoría deben mostrar los nombres de categoría y proveedores cuando están en modo de solo lectura (como ahora) y una lista desplegable de opciones aplicables cuando se editen. Con una lista desplegable, el usuario final puede ver rápidamente qué categorías y proveedores están disponibles para elegir y puede realizar su selección más fácilmente.
Para proporcionar este comportamiento, es necesario convertir las instancias de BoundField SupplierName
y CategoryName
en elementos TemplateField en los que ItemTemplate
emita los valores SupplierName
y CategoryName
, y EditItemTemplate
use un control DropDownList para enumerar las categorías y proveedores disponibles.
Adición de los controles DropDownList Categories
y Suppliers
Para empezar, convierta las instancias de BoundField SupplierName
y CategoryName
en elementos TemplateField; para ello, haga clic en el vínculo Editar columnas de la etiqueta inteligente de GridView; seleccione BoundField en la lista de la parte inferior izquierda y haga clic en el vínculo "Convertir este campo en TemplateField". El proceso de conversión creará una instancia de TemplateField con ItemTemplate
y EditItemTemplate
, como se muestra en la sintaxis declarativa siguiente:
<asp:TemplateField HeaderText="Category" SortExpression="CategoryName">
<EditItemTemplate>
<asp:Label ID="Label1" runat="server"
Text='<%# Eval("CategoryName") %>'></asp:Label>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server"
Text='<%# Bind("CategoryName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
Como BoundField se ha marcado como de solo lectura, ItemTemplate
y EditItemTemplate
contienen un control web de etiqueta cuya propiedad Text
está enlazada al campo de datos aplicable (CategoryName
, en la sintaxis anterior). Es necesario modificar EditItemTemplate
y reemplazar el control web Label por un control DropDownList.
Como ha visto en los tutoriales anteriores, la plantilla se puede editar desde el Diseñador o directamente desde la sintaxis declarativa. Para editarla desde el Diseñador, haga clic en el vínculo Editar plantillas de la etiqueta inteligente de GridView y elija trabajar con el elemento EditItemTemplate
del campo Category. Quite el control web Label y reemplácelo por un control DropDownList, y establezca la propiedad ID de DropDownList en Categories
.
Figura 5: Eliminación de TexBox y adición de un control DropDownList a EditItemTemplate
(haga clic para ver la imagen a tamaño completo)
A continuación, es necesario rellenar DropDownList con las categorías disponibles. Haga clic en el vínculo Elegir origen de datos de la etiqueta inteligente de DropDownList y opte por crear un objeto ObjectDataSource denominado CategoriesDataSource
.
Figura 6: Creación de una instancia de ObjectDataSource con el nombre CategoriesDataSource
(haga clic para ver la imagen a tamaño completo)
Para que esta instancia de ObjectDataSource devuelva todas las categorías, se debe enlazar al método GetCategories()
de la clase CategoriesBLL
.
Figura 7: Enlace de ObjectDataSource al método GetCategories()
de CategoriesBLL
(haga clic para ver la imagen a tamaño completo)
Por último, configure lo valores de DropDownList de modo que el campo CategoryName
se muestre en cada ListItem
de DropDownList con el campo CategoryID
como valor.
Figura 8: Representación del campo CategoryName
y uso de CategoryID
como valor (haga clic para ver la imagen a tamaño completo)
Después de realizar estos cambios, el marcado declarativo para EditItemTemplate
la instancia de TemplateField CategoryName
incluirá DropDownList y ObjectDataSource:
<asp:TemplateField HeaderText="Category" SortExpression="CategoryName">
<EditItemTemplate>
<asp:DropDownList ID="Categories" runat="server"
DataSourceID="CategoriesDataSource"
DataTextField="CategoryName" DataValueField="CategoryID">
</asp:DropDownList>
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server"
Text='<%# Bind("CategoryName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
Nota:
El control DropDownList de EditItemTemplate
debe tener habilitado su estado de visualización. En breve agregará sintaxis de enlace de datos a la sintaxis declarativa de DropDownList y los comandos de enlace de datos como Eval()
y Bind()
solo se pueden mostrar en los controles cuyo estado de visualización está habilitado.
Repita estos pasos para agregar un control DropDownList denominado Suppliers
al elemento EditItemTemplate
de la instancia de TemplateField SupplierName
. Esto implicará agregar un control DropDownList a EditItemTemplate
y crear otra instancia de ObjectDataSource. Pero la instancia de ObjectDataSource del control DropDownList Suppliers
se debe configurar para invocar el método GetSuppliers()
de la clase SuppliersBLL
. Además, configure el control DropDownList Suppliers
para mostrar el campo CompanyName
y usar el campo SupplierID
como valor deListItem
.
Después de agregar los controles DropDownList a las dos instancias de EditItemTemplate
, abra la página en un explorador y haga clic en el botón Editar para el producto Chef Anton's Cajun Seasoning. Como se muestra en la figura 9, las columnas de categoría y proveedor del producto se representan como listas desplegables que contienen las categorías y proveedores disponibles entre las que elegir. Pero observe que los primeros elementos de las dos listas desplegables se seleccionan de forma predeterminada (Beverages para la categoría y Exotic Liquids como proveedor), aunque Chef Anton's Cajun Seasoning sea un producto Condiment suministrado por New Orleans Cajun Delights.
Figura 9: El primer elemento de las listas desplegables está seleccionado de forma predeterminada (haga clic para ver la imagen a tamaño completo)
Además, si hace clic en Actualizar, verá que los valores CategoryID
y SupplierID
del producto se establecen en NULL
. Estos dos comportamientos no deseados se deben a que los controles DropDownList de las instancias de EditItemTemplate
no están enlazados a ningún campo de datos de los datos de producto subyacentes.
Enlace de los controles DropDownList a los campos de datos CategoryID
ySupplierID
Para que las listas desplegables de proveedor y categoría del producto editado se establezcan en los valores adecuados y para que estos valores se envíen de vuelta al método UpdateProduct
de BLL al hacer clic en Actualizar, es necesario enlazar las propiedades SelectedValue
de los controles DropDownList a los campos de datos CategoryID
y SupplierID
mediante el enlace de datos bidireccional. Para lograrlo con el control DropDownList Categories
, puede agregar SelectedValue='<%# Bind("CategoryID") %>'
directamente a la sintaxis declarativa.
Como alternativa, puede establecer los enlaces de datos de DropDownList si edita la plantilla desde el Diseñador y hace clic en el vínculo Editar DataBindings desde la etiqueta inteligente de DropDownList. A continuación, indique que la propiedad SelectedValue
se debe enlazar al campo CategoryID
mediante el enlace de datos bidireccional (vea la figura 10). Repita el proceso declarativo o del Diseñador para enlazar el campo de datos SupplierID
al control DropDownList Suppliers
.
Figura 10: Enlace de CategoryID
a la propiedad SelectedValue
de DropDownList mediante el enlace de datos bidireccional (haga clic para ver la imagen a tamaño completo)
Una vez que se hayan aplicado los enlaces a las propiedades SelectedValue
de los dos controles DropDownList, columnas de categoría y proveedor del producto editado tendrán como valor predeterminado los valores del producto actual. Al hacer clic en Actualizar, los valores CategoryID
y SupplierID
del elemento de lista desplegable seleccionado se pasarán al método UpdateProduct
. En la figura 11 se muestra el tutorial después de agregar las instrucciones de enlace de datos; observe cómo los elementos de lista desplegable seleccionados para Chef Anton's Cajun Seasoning son correctamente Condiment y New Orleans Cajun Delights.
Figura 11: Los valores actuales de categoría y proveedor del producto editado están seleccionados de forma predeterminada (haga clic para ver la imagen a tamaño completo)
Control de valores NULL
Las columnas CategoryID
y SupplierID
de la tabla Products
pueden ser NULL
, pero los controles DropDownList de las instancias de EditItemTemplate
no incluyen un elemento de lista para representar un valor NULL
. Esto tiene dos consecuencias:
- El usuario no puede usar la interfaz para cambiar la categoría o el proveedor de un producto de un valor que no es
NULL
a uno que seaNULL
- Si un producto tiene una instancia de
NULL
CategoryID
oSupplierID
, al hacer clic en el botón Editar se iniciará una excepción. Esto se debe a que el valorNULL
devuelto porCategoryID
(oSupplierID
) en la instrucciónBind()
no se asigna a un valor del control DropDownList (el control DropDownList inicia una excepción cuando su propiedadSelectedValue
está establecida en un valor que no se incluye en su colección de elementos de lista).
Para admitir valores NULL
CategoryID
y SupplierID
, es necesario agregar otra instancia de ListItem
a cada control DropDownList para representar el valor NULL
. En el tutorial Filtrado de maestros y detalles con una lista desplegable, ha visto cómo agregar un elemento ListItem
adicional a un control DropDownList con enlace de datos, lo que implicaba establecer la propiedad AppendDataBoundItems
de DropDownList en True
y agregar manualmente el elemento ListItem
adicional. Pero en ese tutorial anterior se ha agregado un elemento ListItem
con una instancia Value
de -1
. Pero la lógica de enlace de datos en ASP.NET convertirá automáticamente una cadena en blanco en un valor NULL
y viceversa. Por tanto, para este tutorial querrá que Value
de ListItem
sea una cadena vacía.
Para empezar, establezca la propiedad AppendDataBoundItems
de los controles DropDownList en True
. A continuación, agregue NULL
ListItem
mediante la adición del elemento <asp:ListItem>
siguiente a cada control DropDownList para que el marcado declarativo tenga el siguiente aspecto:
<asp:DropDownList ID="Categories" runat="server"
DataSourceID="CategoriesDataSource" DataTextField="CategoryName"
DataValueField="CategoryID" SelectedValue='<%# Bind("CategoryID") %>'
AppendDataBoundItems="True">
<asp:ListItem Value="">(None)</asp:ListItem>
</asp:DropDownList>
Para esta instancia de ListItem
se usa "(None)" como valor de texto, pero si quiere puede cambiarlo para que también sea una cadena en blanco.
Nota:
Como ha visto en el tutorial Filtrado de maestros y detalles con una lista desplegable, puede agregar instancias de ListItem
a un control DropDownList desde el Diseñador si hace clic en la propiedad Items
de DropDownList en la ventana Propiedades (que mostrará el Editor de colecciones ListItem
). Pero en este tutorial asegúrese de agregar NULL
ListItem
mediante la sintaxis declarativa. Si usa el Editor de colecciones ListItem
, la sintaxis declarativa generada omitirá por completo el valor Value
cuando se le asigne una cadena en blanco, y creará marcado declarativo como: <asp:ListItem>(None)</asp:ListItem>
. Aunque esto puede parecer inofensivo, el valor que falta hace que DropDownList use el valor de la propiedad Text
en su lugar. Esto significa que, si se selecciona NULL
ListItem
, se intentará asignar el valor "(None)" a CategoryID
, lo que iniciará una excepción. Al establecer Value=""
de forma explícita, se asignará un valor NULL
a CategoryID
cuando se seleccione NULL
ListItem
.
Repita estos pasos para la lista desplegable Suppliers.
Con esta instancia de ListItem
adicional, la interfaz de edición ahora puede asignar valores NULL
a los campos CategoryID
y SupplierID
de un producto, como se muestra en la figura 12.
Figura 12: Elección de (None) para asignar un valor NULL
para la categoría o el proveedor de un producto (haga clic para ver la imagen a tamaño completo )
Paso 4: Uso de controles RadioButton para el estado interrumpido
Actualmente, el campo de datos Discontinued
de los productos se expresa mediante un control CheckBoxField, que representa una casilla deshabilitada para las filas de solo lectura y una casilla habilitada para la fila que se editan. Aunque esta interfaz de usuario suele ser adecuada, se puede personalizarla si es necesario mediante una instancia de TemplateField. En este tutorial, se cambiará CheckBoxField por una instancia de TemplateField que usa un control RadioButtonList con dos opciones "Active" y "Discontinued" desde las que el usuario puede especificar el valor Discontinued
del producto.
Para empezar, convierta la instancia de CheckBoxField Discontinued
en un control TemplateField, que creará una instancia de TemplateField con ItemTemplate
y EditItemTemplate
. Las dos plantillas incluyen un control CheckBox con su propiedad Checked
enlazada al campo de datos Discontinued
; la única diferencia entre las dos es que la propiedad Enabled
del control CheckBox de ItemTemplate
está establecida en False
.
Reemplace CheckBox en ItemTemplate
y EditItemTemplate
por un control RadioButtonList, y establezca las propiedades ID
de RadioButtonList en DiscontinuedChoice
. A continuación, indique que los controles RadioButtonList deben contener dos botones de radio, uno con la etiqueta "Active" y un valor de "False",y otro con la etiqueta "Discontinued" y un valor de "True". Para ello, puede escribir los elementos <asp:ListItem>
directamente mediante la sintaxis declarativa o usar el Editor de colecciones ListItem
desde el Diseñador. En la figura 13 se muestra el Editor de colecciones ListItem
después de especificar las dos opciones de botón de radio.
Figura 13: Adición de las opciones Active y Discontinued a RadioButtonList (Haga clic para ver la imagen a tamaño completo)
Como el control RadioButtonList de ItemTemplate
no debe ser editable, establezca su propiedad Enabled
en False
y deje la propiedad Enabled
en True
(el valor predeterminado) para RadioButtonList en EditItemTemplate
. Esto hará que los botones de radio de la fila no editada sean de solo lectura, pero permitirá al usuario cambiar los valores de RadioButton de la fila editada.
Todavía es necesario asignar las propiedades SelectedValue
de los controles RadioButtonList para que el botón de radio adecuado se seleccione en función del campo de datos Discontinued
del producto. Como sucede con los controles DropDownList que se han examinado antes en este tutorial, esta sintaxis de enlace de datos se puede agregar directamente al marcado declarativo o desde el vínculo Editar DataBindings en las etiquetas inteligentes de los controles RadioButtonList.
Después de agregar los dos controles RadioButtonList y configurarlos, el marcado declarativo de la instancia de TemplateField Discontinued
debe ser similar al siguiente:
<asp:TemplateField HeaderText="Discontinued" SortExpression="Discontinued">
<ItemTemplate>
<asp:RadioButtonList ID="DiscontinuedChoice" runat="server"
Enabled="False" SelectedValue='<%# Bind("Discontinued") %>'>
<asp:ListItem Value="False">Active</asp:ListItem>
<asp:ListItem Value="True">Discontinued</asp:ListItem>
</asp:RadioButtonList>
</ItemTemplate>
<EditItemTemplate>
<asp:RadioButtonList ID="DiscontinuedChoice" runat="server"
SelectedValue='<%# Bind("Discontinued") %>'>
<asp:ListItem Value="False">Active</asp:ListItem>
<asp:ListItem Value="True">Discontinued</asp:ListItem>
</asp:RadioButtonList>
</EditItemTemplate>
</asp:TemplateField>
Con estos cambios, la columna Discontinued
se ha transformado de una lista de casillas a una lista de pares de botones de radio (vea la figura 14). Al editar un producto, se selecciona el botón de radio adecuado y se puede actualizar el estado de interrupción del producto si se selecciona el otro botón de radio y se hace clic en Actualizar.
Figura 14: Las casillas Discontinued se han reemplazado por pares de botón de radio (haga clic para ver la imagen a tamaño completo)
Nota:
Como la columna Discontinued
de la base de datos Products
no puede tener valores NULL
, no es necesario preocuparse de capturar información de NULL
en la interfaz. Pero si la columna Discontinued
puede contener valores NULL
, podría querer agregar un tercer botón de radio a la lista con Value
establecido en una cadena vacía (Value=""
), al igual que con los controles DropDownList de categoría y proveedor.
Resumen
Aunque BoundField y CheckBoxField representan automáticamente interfaces de edición e inserción de solo lectura, carecen de la capacidad de personalización. Pero a menudo es necesario personalizar la interfaz de edición o inserción, posiblemente con la adición de controles de validación (como en el tutorial anterior), o bien personalizar la interfaz de usuario de recopilación de datos (como en este tutorial). La personalización de la interfaz con un control TemplateField se puede resumir en los pasos siguientes:
- Agregar una instancia de TemplateField o convertir un control BoundField o CheckBoxField existente en TemplateField
- Aumentar la interfaz según sea necesario
- Enlazar los campos de datos adecuados a los controles web recién agregados mediante el enlace de datos bidireccional
Además de usar los controles web integrados de ASP.NET, también puede personalizar las plantillas de TemplateField con controles de servidor compilados y personalizados, y controles de usuario.
¡Feliz programación!
Acerca del autor
Scott Mitchell, autor de siete libros de ASP/ASP.NET y fundador de 4GuysFromRolla.com, ha trabajado 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.