Un examinador para ADO.NET
Por Mauro Sant’Anna
En este artículo veremos cómo crear una barra de herramientas para la navegación en componentes vinculados (“DataBinding”) con ADO.NET, como se muestra a continuación:
Utilizaremos Visual Studio .NET.
El examinador
Ningún componente suministrado con Visual Studio .NET realiza una función que resulta bastante obvia y necesaria: ofrecer una “barra de navegación” para desplazarse por un conjunto de componentes vinculados a la clase DataTable. Tal componente debería tener varios botones para desempeñar funciones como:Resulta interesante comprobar que Visual Studio .NET incluye un asistente llamado Data Form Wizard (Asistente para formularios de datos) en la opción de menú Project | Add New Item (Proyecto | Agregar nuevo elemento) que permite la creación de una aplicación con una barra de navegación similar a la que deseamos. Veamos como ejemplo una aplicación creada para mostrar datos de la tabla Products de la base de datos Northwind de SQL Server:
- Situarse en la primera línea.
- Situarse en la última línea.
- Hacer avanzar la posición actual en una línea.
- Hacer retroceder la posición actual en una línea.
- Eliminar la línea actual.
- Agregar una línea.
![]()
El problema con el conjunto de botones mostrado arriba es que es necesario repetir su código en todos los formularios a los que deseemos agregar esta funcionalidad. Lo que deseamos es escribir un componente que haga lo mismo y que pueda ser utilizado en varios formularios o proyectos.
Creación del componente
El primer paso es crear un nuevo elemento de tipo “Windows Control Library” (Biblioteca de control para Windows) en C#:
Agregue siete componentes de tipo Button y un TextBox al control. A continuación, ajuste el tamaño del control UserControl para que sólo ocupe el área necesaria para mostrar los componentes, sin bordes laterales:
Interceptaremos los eventos Click de todos los botones, así como el evento Load del propio control UserControl. Veamos el código del componente:
#region Properties
private DataTable FTable;
private Control FBindingObject;
[Description("Tabla a recorrer"), DefaultValue(null), Category("Data")]
public DataTable Table {
get {
return FTable;
}
set {
FTable = value;
UpdatePosChange();
}
}
[Description("El control que contiene los componentes a los que desea enlazarse"),
DefaultValue(null), Category("Data")]
public Control BindingObject {
get {
return FBindingObject;
}
set {
FBindingObject = value;
UpdatePosChange();
}
}
#endregion
#region Utility Functions
///
/// Obtener el elemento de enlace para el control y la tabla de datos
///
/// El elemento de enlace o NULL si no está disponible
private BindingManagerBase GetBinder()
{
BindingManagerBase Bnd = null;
if ((FBindingObject != null) && (FTable != null)) {
if (FBindingObject.BindingContext != null) {
Bnd = FBindingObject.BindingContext[FTable];
}
}
return Bnd;
}
///
/// Cancelar el modo de edición
///
private void CancelEdit() {
BindingManagerBase Bnd = GetBinder();
if ((Bnd != null)) {
Bnd.CancelCurrentEdit();
UpdatePosChange();
}
}
///
/// Actualizar el indicador de estado
///
public void UpdatePosChange() {
BindingManagerBase Bnd = GetBinder();
if ((Bnd != null)) {
txtStatus.Text = string.Format("{0} / {1}", Bnd.Position + 1, Bnd.Count);
}
else {
txtStatus.Text = "";
}
}
#endregion
#region Button click events
private void button1_Click(object sender, System.EventArgs e)
{
BindingManagerBase Bnd = GetBinder();
if (Bnd != null) {
Bnd.Position = 0;
UpdatePosChange();
}
}
private void button2_Click(object sender, System.EventArgs e)
{
BindingManagerBase Bnd = GetBinder();
if (Bnd != null) {
Bnd.Position = Math.Max(Bnd.Position -1, 0);
UpdatePosChange();
}
}
private void button3_Click(object sender, System.EventArgs e)
{
BindingManagerBase Bnd = GetBinder();
if (Bnd != null) {
Bnd.Position = Math.Min(Bnd.Position + 1, Bnd.Count);
UpdatePosChange();
}
}
private void button4_Click(object sender, System.EventArgs e)
{
BindingManagerBase Bnd = GetBinder();
if (Bnd != null) {
Bnd.Position = Bnd.Count;
UpdatePosChange();
}
}
private void button5_Click(object sender, System.EventArgs e)
{
BindingManagerBase Bnd = GetBinder();
if ((Bnd != null)) {
Bnd.RemoveAt(Bnd.Position);
UpdatePosChange();
}
}
private void button6_Click(object sender, System.EventArgs e)
{
BindingManagerBase Bnd = GetBinder();
if ((Bnd != null)) {
Bnd.AddNew();
UpdatePosChange();
}
}
private void button7_Click(object sender, System.EventArgs e)
{
CancelEdit();
}
#endregion
#region Component Events
private void UserControl1_Load(object sender, System.EventArgs e)
{
UpdatePosChange();
}
#endregion
Para usar el componente, es necesario situarlo sobre un formulario y ajustar dos propiedades:Usted debe seguir utilizando los componentes de base de datos (DataAdapter, DataSet etc) de la forma normal. En definitiva, cuando exista un conjunto de resultados, podrá navegar por él.
- BindingObject: Clase derivada del Control sobre el que se encuentran los componentes vinculados. Normalmente es el formulario, pero puede ser un control Panel GroupBox.
- Table: La tabla que se desea vincular. Los controles deben ser vinculados exactamente a esta tabla. Si la tabla se encuentra dentro de un conjunto de datos, el vínculo debe ser a DataSet.Table.
Veamos un ejemplo:
![]()
Veamos el código de los dos botones adicionales:
// Ejecutar la consulta
private void button1_Click(object sender, System.EventArgs e)
{
sqlDataAdapter1.Fill(dataSet11);
bar1.UpdatePosChange();
}
// Actualizar
private void button2_Click(object sender, System.EventArgs e)
{
if (dataSet11.HasChanges()) {
DataSet Changes = dataSet11.GetChanges();
sqlDataAdapter1.Update(Changes);
dataSet11.AcceptChanges();
}
}
Conclusión
La creación de un componente para navegar por un conjunto de resultados puede facilitar en gran medida la programación con ADO.NET.


LinkBack URL
About LinkBacks
Utilizaremos Visual Studio .NET.


