Vous êtes sur la page 1sur 20

Programacin con formularios Windows Forms

Tutorial: Implementar el modo virtual en el control DataGridView de


formularios Windows Forms
Vea tambin
Contraer todo Expandir todo
Filtro de lenguaje: Todos Filtro de lenguaje: Mltiple
Filtro de lenguaje: Visual Basic Filtro de lenguaje: C# Filtro de lenguaje: C++ Filtro de
lenguaje: J# Filtro de lenguaje: JScript
Visual Basic (Declaracin)
Visual Basic (Uso)
C#
C++
J#
JScript
Si desea mostrar grandes volmenes de datos en formato de tabla en un control DataGridView, puede
establecer la propiedad VirtualMode en true y administrar de forma explcita la interaccin del control
con el almacn de datos. Esto le permite ajustar el rendimiento del control en esta situacin.
El control DataGridView proporciona varios eventos que puede controlar para interactuar con un
almacn de datos personalizado. Este tutorial le gua a travs del proceso de implementar estos
controladores de eventos. En el ejemplo de cdigo de este tema se utiliza un origen de datos muy
sencillo para fines de ilustracin. En una configuracin de produccin, normalmente cargar slo las
filas que necesite mostrar en cach y controlar eventos DataGridView para interactuar con la cach
y actualizarla. Para obtener ms informacin, vea Implementar el modo virtual mediante la carga de
datos Just-In-Time en el control DataGridView de formularios Windows Forms
Para copiar el cdigo de este tema como un listado sencillo, vea Cmo: Implementar el modo virtual
en el control DataGridView de formularios Windows Forms.

Crear el formulario
Para implementar el modo virtual
1.

Cree una clase que deriva de Form y contiene un control DataGridView.


El cdigo siguiente contiene alguna inicializacin bsica. Se declaran algunas variables que se
utilizarn en pasos posteriores, se proporciona un mtodo Main y un diseo de formulario
sencillo del constructor de clase.

Visual Basic

Copiar cdigo

Imports System
Imports System.Windows.Forms
Public Class Form1
Inherits Form
Private WithEvents dataGridView1 As New
DataGridView()

' Declare an ArrayList to serve as the data


store.
Private customers As New
System.Collections.ArrayList()
' Declare a Customer object to store data for a
row being edited.
Private customerInEdit As Customer
' Declare a variable to store the index of a
row being edited.
' A value of -1 indicates that there is no row
currently in edit.
Private rowInEdit As Integer = -1
' Declare a variable to indicate the commit
scope.
' Set this value to false to use cell-level
commit scope.
Private rowScopeCommit As Boolean = True
<STAThreadAttribute()> _
Public Shared Sub Main()
Application.Run(New Form1())
End Sub
Public Sub New()
' Initialize the form.
Me.dataGridView1.Dock = DockStyle.Fill
Me.Controls.Add(Me.dataGridView1)
Me.Text = "DataGridView virtual-mode demo
(row-level commit scope)"
End Sub
...
End Class
C#

Copiar cdigo

using System;
using System.Windows.Forms;
public class Form1 : Form
{
private DataGridView dataGridView1 = new
DataGridView();
// Declare an ArrayList to serve as the data
store.
private System.Collections.ArrayList customers
=
new System.Collections.ArrayList();
// Declare a Customer object to store data for
a row being edited.
private Customer customerInEdit;
// Declare a variable to store the index of a
row being edited.
// A value of -1 indicates that there is no row
currently in edit.
private int rowInEdit = -1;
// Declare a variable to indicate the commit
scope.
// Set this value to false to use cell-level
commit scope.
private bool rowScopeCommit = true;
[STAThreadAttribute()]
public static void Main()
{
Application.Run(new Form1());
}
public Form1()
{
// Initialize the form.
this.dataGridView1.Dock = DockStyle.Fill;

this.Controls.Add(this.dataGridView1);
this.Load += new EventHandler(Form1_Load);
this.Text = "DataGridView virtual-mode demo
(row-level commit scope)";
}
...
}
2.

Implemente un controlador para el evento Load del formulario que inicializa el control
DataGridView y rellena el almacn de datos con valores de ejemplo.

Visual Basic

Copiar cdigo

Private Sub Form1_Load(ByVal sender As Object,


ByVal e As EventArgs) _
Handles Me.Load
' Enable virtual mode.
Me.dataGridView1.VirtualMode = True
' Add columns to the DataGridView.
Dim companyNameColumn As New
DataGridViewTextBoxColumn()
With companyNameColumn
.HeaderText = "Company Name"
.Name = "Company Name"
End With
Dim contactNameColumn As New
DataGridViewTextBoxColumn()
With contactNameColumn
.HeaderText = "Contact Name"
.Name = "Contact Name"
End With
Me.dataGridView1.Columns.Add(companyNameColumn)
Me.dataGridView1.Columns.Add(contactNameColumn)
Me.dataGridView1.AutoSizeColumnsMode = _
DataGridViewAutoSizeColumnsMode.AllCells
' Add some sample entries to the data store.
Me.customers.Add(New Customer("Bon app'",

"Laurence Lebihan"))
Me.customers.Add(New Customer("Bottom-Dollar
Markets", _
"Elizabeth Lincoln"))
Me.customers.Add(New Customer("B's Beverages",
"Victoria Ashworth"))
' Set the row count, including the row for new
records.
Me.dataGridView1.RowCount = 4
End Sub
C#

Copiar cdigo

private void Form1_Load(object sender, EventArgs e)


{
// Enable virtual mode.
this.dataGridView1.VirtualMode = true;
// Connect the virtual-mode events to event handlers.
this.dataGridView1.CellValueNeeded += new

DataGridViewCellValueEventHandler(dataGridView1_CellValueNeed
this.dataGridView1.CellValuePushed += new

DataGridViewCellValueEventHandler(dataGridView1_CellValuePush
this.dataGridView1.NewRowNeeded += new
DataGridViewRowEventHandler(dataGridView1_NewRowNeede
this.dataGridView1.RowValidated += new
DataGridViewCellEventHandler(dataGridView1_RowValidat
this.dataGridView1.RowDirtyStateNeeded += new
QuestionEventHandler(dataGridView1_RowDirtyStateNeede
this.dataGridView1.CancelRowEdit += new
QuestionEventHandler(dataGridView1_CancelRowEdit);
this.dataGridView1.UserDeletingRow += new

DataGridViewRowCancelEventHandler(dataGridView1_UserDeletingR
// Add columns to the DataGridView.
DataGridViewTextBoxColumn companyNameColumn = new

DataGridViewTextBoxColumn();
companyNameColumn.HeaderText = "Company Name";
companyNameColumn.Name = "Company Name";
DataGridViewTextBoxColumn contactNameColumn = new
DataGridViewTextBoxColumn();
contactNameColumn.HeaderText = "Contact Name";
contactNameColumn.Name = "Contact Name";
this.dataGridView1.Columns.Add(companyNameColumn);
this.dataGridView1.Columns.Add(contactNameColumn);
this.dataGridView1.AutoSizeColumnsMode =
DataGridViewAutoSizeColumnsMode.AllCells;
// Add some sample entries to the data store.
this.customers.Add(new Customer(
"Bon app'", "Laurence Lebihan"));
this.customers.Add(new Customer(
"Bottom-Dollar Markets", "Elizabeth Lincoln"));
this.customers.Add(new Customer(
"B's Beverages", "Victoria Ashworth"));

}
4.

// Set the row count, including the row for new records.
this.dataGridView1.RowCount = 4;
Implemente un controlador para el evento CellValueNeeded que recupera el valor de celda
solicitado del almacn de datos o el objeto Customer actualmente en edicin.
Este evento aparece cada vez que el control DataGridView tiene que dibujar una celda.

Visual Basic

Copiar cdigo

Private Sub dataGridView1_CellValueNeeded(ByVal


sender As Object, _
ByVal e As
System.Windows.Forms.DataGridViewCellValueEventArgs)
_
Handles dataGridView1.CellValueNeeded
' If this is the row for new records, no values
are needed.
If e.RowIndex = Me.dataGridView1.RowCount - 1
Then
Return
End If

Dim customerTmp As Customer = Nothing


' Store a reference to the Customer object for
the row being painted.
If e.RowIndex = rowInEdit Then
customerTmp = Me.customerInEdit
Else
customerTmp =
CType(Me.customers(e.RowIndex), Customer)
End If
' Set the cell value to paint using the Customer
object retrieved.
Select Case
Me.dataGridView1.Columns(e.ColumnIndex).Name
Case "Company Name"
e.Value = customerTmp.CompanyName
Case "Contact Name"
e.Value = customerTmp.ContactName
End Select
End Sub
C#

Copiar cdigo

private void dataGridView1_CellValueNeeded(object


sender,
System.Windows.Forms.DataGridViewCellValueEventArgs
e)
{
// If this is the row for new records, no
values are needed.
if (e.RowIndex == this.dataGridView1.RowCount 1) return;
Customer customerTmp = null;
// Store a reference to the Customer object for

the row being painted.


if (e.RowIndex == rowInEdit)
{
customerTmp = this.customerInEdit;
}
else
{
customerTmp =
(Customer)this.customers[e.RowIndex];
}
// Set the cell value to paint using the
Customer object retrieved.
switch
(this.dataGridView1.Columns[e.ColumnIndex].Name)
{
case "Company Name":
e.Value = customerTmp.CompanyName;
break;
case "Contact Name":
e.Value = customerTmp.ContactName;
break;
}
5.

}
Implemente un controlador para el evento CellValuePushed que almacena un valor de celda
editado en el objeto Customer que representa la fila editada. Este evento se produce cada vez
que el usuario confirma un cambio de valor de celda.

Visual Basic

Copiar cdigo

Private Sub dataGridView1_CellValuePushed(ByVal


sender As Object, _
ByVal e As
System.Windows.Forms.DataGridViewCellValueEventArgs)
_
Handles dataGridView1.CellValuePushed
Dim customerTmp As Customer = Nothing
' Store a reference to the Customer object for
the row being edited.

If e.RowIndex < Me.customers.Count Then


' If the user is editing a new row, create a
new Customer object.
If Me.customerInEdit Is Nothing Then
Me.customerInEdit = New Customer( _
CType(Me.customers(e.RowIndex),
Customer).CompanyName, _
CType(Me.customers(e.RowIndex),
Customer).ContactName)
End If
customerTmp = Me.customerInEdit
Me.rowInEdit = e.RowIndex
Else
customerTmp = Me.customerInEdit
End If
' Set the appropriate Customer property to the
cell value entered.
Dim newValue As String = TryCast(e.Value,
String)
Select Case
Me.dataGridView1.Columns(e.ColumnIndex).Name
Case "Company Name"
customerTmp.CompanyName = newValue
Case "Contact Name"
customerTmp.ContactName = newValue
End Select
End Sub
C#

Copiar cdigo

private void dataGridView1_CellValuePushed(object


sender,
System.Windows.Forms.DataGridViewCellValueEventArgs
e)
{
Customer customerTmp = null;

// Store a reference to the Customer object for


the row being edited.
if (e.RowIndex < this.customers.Count)
{
// If the user is editing a new row, create
a new Customer object.
if (this.customerInEdit == null)
{
this.customerInEdit = new Customer(
((Customer)this.customers[e.RowIndex]).CompanyName,
((Customer)this.customers[e.RowIndex]).ContactName);
}
customerTmp = this.customerInEdit;
this.rowInEdit = e.RowIndex;
}
else
{
customerTmp = this.customerInEdit;
}
// Set the appropriate Customer property to the
cell value entered.
String newValue = e.Value as String;
switch
(this.dataGridView1.Columns[e.ColumnIndex].Name)
{
case "Company Name":
customerTmp.CompanyName = newValue;
break;

case "Contact Name":


customerTmp.ContactName = newValue;
break;

}
7.

Implemente un controlador para el evento NewRowNeeded que crea un nuevo objeto

Customer que representa una fila recin creada.

Este evento aparece cada vez que el usuario especifica la fila de nuevos registros.

Visual Basic

Copiar cdigo

Private Sub dataGridView1_NewRowNeeded(ByVal sender


As Object, _
ByVal e As
System.Windows.Forms.DataGridViewRowEventArgs) _
Handles dataGridView1.NewRowNeeded
' Create a new Customer object when the user
edits
' the row for new records.
Me.customerInEdit = New Customer()
Me.rowInEdit = Me.dataGridView1.Rows.Count - 1
End Sub
C#

Copiar cdigo

private void dataGridView1_NewRowNeeded(object


sender,
System.Windows.Forms.DataGridViewRowEventArgs
e)
{
// Create a new Customer object when the user
edits
// the row for new records.
this.customerInEdit = new Customer();
this.rowInEdit = this.dataGridView1.Rows.Count
- 1;
}
8.

Implemente un controlador para el evento RowValidated que guarda las filas nuevas o
modificadas en el almacn de datos.
Este evento aparece cada vez que el usuario cambia la fila actual.

Visual Basic

Copiar cdigo

Private Sub dataGridView1_RowValidated(ByVal sender


As Object, _
ByVal e As
System.Windows.Forms.DataGridViewCellEventArgs) _
Handles dataGridView1.RowValidated
' Save row changes if any were made and release
the edited

' Customer object if there is one.


If e.RowIndex >= Me.customers.Count AndAlso _
e.RowIndex <> Me.dataGridView1.Rows.Count 1 Then
store.

' Add the new Customer object to the data


Me.customers.Add(Me.customerInEdit)
Me.customerInEdit = Nothing
Me.rowInEdit = -1

ElseIf Not (Me.customerInEdit Is Nothing)


AndAlso _
e.RowIndex < Me.customers.Count Then
' Save the modified Customer object in the
data store.
Me.customers(e.RowIndex) =
Me.customerInEdit
Me.customerInEdit = Nothing
Me.rowInEdit = -1
ElseIf Me.dataGridView1.ContainsFocus Then
Me.customerInEdit = Nothing
Me.rowInEdit = -1
End If
End Sub
C#

Copiar cdigo

private void dataGridView1_RowValidated(object


sender,
System.Windows.Forms.DataGridViewCellEventArgs
e)
{
// Save row changes if any were made and
release the edited
// Customer object if there is one.

if (e.RowIndex >= this.customers.Count &&


e.RowIndex != this.dataGridView1.Rows.Count
- 1)
{
// Add the new Customer object to the data
store.
this.customers.Add(this.customerInEdit);
this.customerInEdit = null;
this.rowInEdit = -1;
}
else if (this.customerInEdit != null &&
e.RowIndex < this.customers.Count)
{
// Save the modified Customer object in the
data store.
this.customers[e.RowIndex] =
this.customerInEdit;
this.customerInEdit = null;
this.rowInEdit = -1;
}
else if (this.dataGridView1.ContainsFocus)
{
this.customerInEdit = null;
this.rowInEdit = -1;
}
}
9.

Implemente un controlador para el evento RowDirtyStateNeeded que indica si se producir el


evento CancelRowEdit cuando el usuario seale la inversin de fila presionando dos veces ESC
en el modo de edicin o una vez fuera del modo de edicin.
De forma predeterminada, se produce el evento CancelRowEdit con la inversin de fila
cuando se ha modificado alguna celda de la fila actual, a no ser que la propiedad
System.Windows.Forms.QuestionEventArgs.Response est establecida en true en el
controlador de eventos RowDirtyStateNeeded. Este evento resulta de utilidad cuando se
determina el mbito de la confirmacin en tiempo de ejecucin.

Visual Basic

Copiar cdigo

Private Sub dataGridView1_RowDirtyStateNeeded(ByVal


sender As Object, _
ByVal e As
System.Windows.Forms.QuestionEventArgs) _
Handles dataGridView1.RowDirtyStateNeeded
If Not rowScopeCommit Then

' In cell-level commit scope, indicate


whether the value
' of the current cell has been modified.
e.Response =
Me.dataGridView1.IsCurrentCellDirty
End If
End Sub
C#

Copiar cdigo

private void
dataGridView1_RowDirtyStateNeeded(object sender,
System.Windows.Forms.QuestionEventArgs e)
{
if (!rowScopeCommit)
{
// In cell-level commit scope, indicate
whether the value
// of the current cell has been modified.
e.Response =
this.dataGridView1.IsCurrentCellDirty;
}
}
10. Implemente un controlador para el evento CancelRowEdit que descarta los valores del
objeto Customer que representa la fila actual.
Se produce este evento cuando el usuario seala la reversin de la fila presionando dos veces
ESC en modo de edicin o una vez fuera del modo de edicin. No se produce este evento si no
se ha modificado ninguna celda de la fila actual o si se ha establecido el valor de la propiedad
System.Windows.Forms.QuestionEventArgs.Response en false en un controlador de
eventos RowDirtyStateNeeded.

Visual Basic

Copiar cdigo

Private Sub dataGridView1_CancelRowEdit(ByVal


sender As Object, _
ByVal e As
System.Windows.Forms.QuestionEventArgs) _
Handles dataGridView1.CancelRowEdit
If Me.rowInEdit = Me.dataGridView1.Rows.Count 2 AndAlso _
Me.rowInEdit = Me.customers.Count Then

' If the user has canceled the edit of a


newly created row,
' replace the corresponding Customer object
with a new, empty one.
Me.customerInEdit = New Customer()
Else
' If the user has canceled the edit of an
existing row,
' release the corresponding Customer
object.
Me.customerInEdit = Nothing
Me.rowInEdit = -1
End If
End Sub
C#

Copiar cdigo

private void dataGridView1_CancelRowEdit(object


sender,
System.Windows.Forms.QuestionEventArgs e)
{
if (this.rowInEdit ==
this.dataGridView1.Rows.Count - 2 &&
this.rowInEdit == this.customers.Count)
{
// If the user has canceled the edit of a
newly created row,
// replace the corresponding Customer
object with a new, empty one.
this.customerInEdit = new Customer();
}
else
{
// If the user has canceled the edit of an
existing row,
// release the corresponding Customer

object.
this.customerInEdit = null;
this.rowInEdit = -1;
}

11. Implemente un controlador para el evento UserDeletingRow que suprime un objeto Customer
existente del almacn de datos o descarta un objeto Customer no guardado que representa
una fila recin creada.
Se produce este evento siempre que el usuario elimina una fila haciendo clic en un encabezado
de fila y presionando la tecla SUPR.

Visual Basic

Copiar cdigo

Private Sub dataGridView1_UserDeletingRow(ByVal


sender As Object, _
ByVal e As
System.Windows.Forms.DataGridViewRowCancelEventArgs)
_
Handles dataGridView1.UserDeletingRow
If e.Row.Index < Me.customers.Count Then
' If the user has deleted an existing row,
remove the
' corresponding Customer object from the
data store.
Me.customers.RemoveAt(e.Row.Index)
End If
If e.Row.Index = Me.rowInEdit Then
' If the user has deleted a newly created
row, release
' the corresponding Customer object.
Me.rowInEdit = -1
Me.customerInEdit = Nothing
End If
End Sub
C#

Copiar cdigo

private void dataGridView1_UserDeletingRow(object


sender,
System.Windows.Forms.DataGridViewRowCancelEventArgs
e)
{
if (e.Row.Index < this.customers.Count)
{
// If the user has deleted an existing row,
remove the
// corresponding Customer object from the
data store.
this.customers.RemoveAt(e.Row.Index);
}
if (e.Row.Index == this.rowInEdit)
{
// If the user has deleted a newly created
row, release
// the corresponding Customer object.
this.rowInEdit = -1;
this.customerInEdit = null;
}
}
12. Implemente una clase Customers simple para representar los elementos de datos utilizados
por este ejemplo de cdigo.

Visual Basic

Copiar cdigo

Public Class Customer


Private companyNameValue As String
Private contactNameValue As String
Public Sub New()
' Leave fields empty.
End Sub
Public Sub New(ByVal companyName As String,
ByVal contactName As String)
companyNameValue = companyName
contactNameValue = contactName

End Sub
Public Property CompanyName() As String
Get
Return companyNameValue
End Get
Set(ByVal value As String)
companyNameValue = value
End Set
End Property
Public Property ContactName() As String
Get
Return contactNameValue
End Get
Set(ByVal value As String)
contactNameValue = value
End Set
End Property
End Class
C#

Copiar cdigo

public class Customer


{
private String companyNameValue;
private String contactNameValue;
public Customer()
{
// Leave fields empty.
}
public Customer(String companyName, String
contactName)
{
companyNameValue = companyName;
contactNameValue = contactName;
}

public String CompanyName


{
get
{
return companyNameValue;
}
set
{
companyNameValue = value;
}
}
public String ContactName
{
get
{
return contactNameValue;
}
set
{
contactNameValue = value;
}
}
}
Probar la aplicacin
Puede comprobar el formulario para asegurarse de que se comporta de la forma prevista.

Para comprobar el formulario

Compile y ejecute la aplicacin.


Aparecer un control DataGridView rellenado con tres registros del cliente. Puede modificar los
valores de varias celdas de una fila y presionar dos veces ESC en el modo de edicin y una vez
fuera de ste modo para invertir la fila completa a sus valores originales. Cuando modifica,
agrega o elimina filas del control, se modifican, agregan o eliminan objetos Customer del
almacn de datos, tambin.

Pasos siguientes
Esta aplicacin proporciona conocimientos bsicos de los eventos que debe controlar para implementar
el modo virtual en el control DataGridView. Puede mejorar esta aplicacin bsica de varios maneras:

Implemente un almacn de datos que almacena en memoria cach los valores de una base de
datos externa. La cach recuperar y descartar valores segn sea necesario de modo que slo
contenga lo que es necesario para la presentacin a la vez que utiliza una pequea cantidad de
memoria en el equipo cliente.

Ajuste el rendimiento del almacn de datos en funcin de sus requisitos. Por ejemplo, quiz
desee compensar las conexiones de red ralentizadas en lugar de las limitaciones de memoria del
equipo cliente utilizando un tamao mayor de cach y minimizando el nmero de consultas de
base de datos.

Para obtener ms informacin sobre cmo almacenar en memoria cach valores de una base de datos
externa, vea Cmo: Implementar el modo virtual con la carga de datos Just-In-Time en el control
DataGridView de formularios Windows Forms.

Vea tambin
Tareas
Cmo: Implementar el modo virtual en el control DataGridView de formularios Windows Forms

Referencia
DataGridView
VirtualMode
CellValueNeeded
CellValuePushed
NewRowNeeded
RowValidated
RowDirtyStateNeeded
CancelRowEdit
UserDeletingRow

Conceptos
Procedimientos recomendados para ajustar la escala del control DataGridView en formularios Windows
Forms
Implementar el modo virtual mediante la carga de datos Just-In-Time en el control DataGridView de
formularios Windows Forms

Otros recursos
Ajuste del rendimiento del control DataGridView en formularios Windows Forms
Para realizar una sugerencia o comunicar un error sobre la Ayuda u otra funcin de este producto, vaya al sitio
Product Feedback Center.

Vous aimerez peut-être aussi