He visto muchas preguntas iguales o similares en foros: ¿Cómo coloco casillas de verificación, cuadros de texto, etc. en cada fila de mi DataGrid? ¿Cómo actualizar sus valores? La respuesta es bastante simple y en este artículo te mostraré cómo hacerlo.
Todos sabemos que DataGrid es una herramienta muy poderosa. En mi experiencia, más del 90% de las veces, DataGrid se utiliza para mostrar datos y posiblemente editarlos una fila a la vez. A veces, es posible que necesites editar varias filas o incluso todos los datos a la vez. Un ejemplo práctico sería una aplicación que vende artículos en línea, donde los clientes podrían querer cambiar uno o más artículos en su carrito a la vez, haciendo clic en las casillas de verificación para eliminar los artículos que no desean.
Concepto
En este ejemplo, escribí un formulario web simple para administrar una lista de contactos almacenada en XML. El requisito es muy simple: tener la capacidad de agregar nuevos contactos, editar/eliminar contactos existentes. Los usuarios pueden modificar o eliminar varios contactos a la vez y también les permito ordenar la cuadrícula de datos por columnas de su elección.
Mis ejemplos están escritos en C#. Si prefiere la versión VB de estos códigos, el código está disponible en ambos formatos en el archivo de descarga.
El archivo de datos XML en el
ejemploContacts.xml
es muy simple e intuitivo.Como es muy simple, no creé un plan.
<?xml versión="1.0" independiente="sí"?>
<Contactos>
<Contacto>
<Correo electrónico>midirecció[email protected]</Correo electrónico>
<Nombre>Juan</Nombre>
<Apellido>Doe</Apellido>
</Contacto>
<Contacto>
<Correo electrónico>tu direcció[email protected]</Correo electrónico>
<Nombre>Jane</Nombre>
<Apellido>Doe</Apellido>
</Contacto>
</Contacts>
ContactList.aspx
Configurar un formulario web es muy sencillo. Coloqué un nuevo DataGrid en mi formulario y lo configuré para que tuviera 4 columnas, y la primera columna contenía casillas de verificación para eliminar contactos. Notarás que lo principal que hice aquí fue crear cada columna como una columna de plantilla (TemplateColumn). Esto me permite colocar objetos de cuadro de texto y casilla de verificación en la plantilla de datos (ItemTemplate). Este es un truco para mostrar algo más que texto en cada fila de la cuadrícula. Además, notarás que uso FooterTemplate para que la creación de nuevos contactos sea fácil e intuitiva.
También incluí un LinkButton para guardar modificaciones y eliminaciones realizadas por el usuario. Pero no se utiliza para agregar nuevos contactos. La operación de agregar nuevos contactos se completa con el botón de enlace (LinkButton) en la plantilla de pie de página de la última columna.
<asp:datagrid id="dgContacts" runat="servidor" ShowFooter="True" AllowSorting="True" Forefont color="Black" GridLines="None" CellPadding="2" Backfont color="LightGoldenrodYellow" BorderWidth="1px " Borderfont color="Tan" Ancho="499px" AutoGenerateColumns="False" DataKeyField="Correo electrónico">
<SelectedItemStyle color de fuente anterior="GhostWhite" color de fuente posterior="DarkSlateBlue"></SelectedItemStyle>
<AlternatingItemStyle Backfont color="PaleGoldenrod"></AlternatingItemStyle>
<HeaderStyle Font-Bold="True" Backfont color="Tan"></HeaderStyle>
<FooterStyle Backfont color="Tan"></FooterStyle>
<Columnas>
<asp:TemplateColumn SortExpression="Nombre" HeaderText="Nombre">
<Plantilla de artículo>
<asp:TextBox id=Primer runat="servidor" Ancho="109px" Texto='<%# DataBinder.Eval(Contenedor, "DataItem.FirstName") %>'>
</asp:Cuadro de texto>
</ItemTemplate>
<Plantilla de pie de página>
<asp:TextBox id="NewFirst" runat="servidor" Ancho="109px"></asp:TextBox>
</Plantilla de pie de página>
</asp:ColumnaPlantilla>
<asp:TemplateColumn SortExpression="Apellido" HeaderText="Apellido">
<Plantilla de artículo>
<asp:TextBox id=Último runat="servidor" Ancho="109px" Texto='<%# DataBinder.Eval(Contenedor, "DataItem.LastName") %>'>
</asp:Cuadro de texto>
</ItemTemplate>
<Plantilla de pie de página>
<asp:TextBox id="NuevoÚltimo" runat="servidor" Ancho="109px"></asp:TextBox>
</Plantilla de pie de página>
</asp:ColumnaPlantilla>
<asp:TemplateColumn SortExpression="Correo electrónico" HeaderText="Correo electrónico">
<Plantilla de artículo>
<asp:TextBox id=Correo electrónico runat="servidor" Texto='<%# DataBinder.Eval(Contenedor, "DataItem.Email") %>'>
</asp:Cuadro de texto>
</ItemTemplate>
<Plantilla de pie de página>
<asp:TextBox id="NuevoCorreo electrónico" runat="servidor"></asp:TextBox>
</Plantilla de pie de página>
</asp:ColumnaPlantilla>
<asp:TemplateColumn HeaderText="Eliminar contacto">
<ItemStyle HorizontalAlign="Centro"></ItemStyle>
<Plantilla de artículo>
<asp:CheckBox Runat="servidor" ID="chkDelete"></asp:CheckBox>
</ItemTemplate>
<FooterStyle HorizontalAlign="Centro"></FooterStyle>
<Plantilla de pie de página>
<asp:LinkButton Runat="servidor" Text="Agregar" CommandName="Agregar" ID="Linkbutton1" NAME="Linkbutton1"></asp:LinkButton>
</Plantilla de pie de página>
</asp:ColumnaPlantilla>
</Columnas>
</asp:cuadrícula de datos>
ContactList.cs
Después de elegir usar un archivo XML para acceder a los datos, decidí usar un DataSet para acceder a ellos. Debido a que el objeto DataSet tiene métodos ReadXml y WriteXml, esta es una elección muy razonable. El primer paso es leer los datos en XML. Como puede ver en el código, creé un miembro para encargarse de ordenar los datos.
conjunto de datos privado _dsContacts;
cadena privada _sSort;
Page_Load vacío privado (remitente del objeto, System.EventArgs e)
{
//Cargar archivo XML.
_dsContacts = nuevo conjunto de datos();
_dsContacts.ReadXml(Server.MapPath("Contactos.xml"));
DataColumn[] dcPk = {_dsContacts.Tables["Contacto"].Columnas["Correo electrónico"]};
_dsContacts.Tables["Contacto"].PrimaryKey = dcPk;
si (!Page.IsPostBack)
{
// Si se carga por primera vez, vincula los datos.
VincularContactos();
_sSort = "Nombre";
}
demás
{
// De lo contrario, lea el estado de clasificación desde el estado de vista.
_sSort = (cadena)ViewState["Ordenar"];
}
}
En el segundo paso, creé un método para vincular datos a la cuadrícula, que incluía lógica de clasificación de datos y métodos para leer datos del disco.
vacío privado BindContacts()
{
//Guardar el estado de clasificación para ver el estado.
ViewState["Sort"] = _sSort;
// Vincula la cuadrícula a la vista de datos ordenados.
DataView dv = nuevo DataView(_dsContacts.Tables["Contacto"]);
dv.Sort = _sSort;
dgContactos.DataSource = dv;
dgContactos.DataBind();
}
privado vacío GuardarContactos()
{
_dsContacts.WriteXml(Server.MapPath("Contactos.xml"));
}
El evento ItemCommand se utiliza para manejar la adición de nuevos contactos a la lista. Nota: Verifiqué si el parámetro CommandName es Agregar. Es para manejar el valor de retorno del botón de enlace (LinkButton) en la plantilla de pie de página (FooterTemplate) de la última columna de la cuadrícula en la página ASPX.
vacío privado dgContacts_ItemCommand (fuente del objeto, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
//Agrego nuevos datos al conjunto de datos. Aquí uso una matriz para mejorar la eficiencia del procesamiento.
if (e.CommandName == "Agregar")
{
cadena[] sContacto = {"", "", ""};
sContact[0] = ((TextBox)e.Item.FindControl("NewEmail")).Texto;
sContact[1] = ((TextBox)e.Item.FindControl("NewFirst")).Texto;
sContact[2] = ((TextBox)e.Item.FindControl("NewLast")).Text;
_dsContacts.Tables["Contacto"].Rows.Add(sContacts
());
}
VincularContactos();
}
Me salté el código SortCommand porque hay muchos otros documentos que tratan la clasificación con gran detalle. Si descarga el código fuente de este ejemplo, estará incluido.
Finalmente, moví el evento de clic (onClick) del botón de enlace (LinkButton) en el formulario aquí. Aquí recorro los elementos de datos en DataGrid para realizar las operaciones de eliminación y actualización necesarias.
btnUpdate_Click vacío privado (remitente del objeto, System.EventArgs e)
{
// Recorre cada elemento de datos.
foreach (DataGridItem en dgContacts.Items)
{
// Asegúrate de que sea un elemento de datos y no la parte superior o inferior de la página.
si (di.ItemType == ListItemType.Item || di.ItemType == ListItemType.AlternatingItem)
{
// Obtiene la fila actual después de realizar la operación de actualización o eliminación.
DataRow dr = _dsContacts.Tables["Contact"].Rows.Find(dgContacts.DataKeys[di.ItemIndex]
// Compruebe si es necesario eliminar una fila.
si (((CheckBox)di.FindControl("chkDelete")).Marcado)
{
_dsContacts.Tables["Contact"].Rows.Remove(dr);//Eliminar la fila especificada
}
demás
{
//Actualizar fila de datos.
dr["Correo electrónico"] = ((TextBox)di.FindControl("Correo electrónico")).Texto;
dr["FirstName"] = ((TextBox)di.FindControl("First")).Texto;
dr["Apellido"] = ((TextBox)di.FindControl("Apellido")).Texto;
}
}
}
//Guardarlo si hay cambios.
si (_dsContacts.HasChanges())
{
GuardarContactos();
}
BindContacts();//Enlace
}
Conclusión
Puedo encontrar fácilmente las celdas (Cells) de cada DataGridItem en el control a través de la posición del control. Hay varias formas de lograr esto y estoy seguro de que puede encontrar una mejor manera de realizar esta tarea. Como puedes ver, editar toda la cuadrícula de datos a la vez es muy sencillo. El mismo método también se puede utilizar para cuadrículas paginadas con ligeras modificaciones.