Tutorial: Implementar el modo virtual en el control DataGridView de formularios Windows Forms
Cuando quiera mostrar cantidades muy grandes de datos tabulares en un control DataGridView, puede establecer la propiedad VirtualMode en true
y gestionar explícitamente la interacción del control con su almacén de datos. Esto le permite ajustar el rendimiento del control en esta situación.
El control DataGridView proporciona varios eventos que puede controlar para interactuar con un almacén de datos personalizado. Este tutorial le guía por el proceso de implementación de estos controladores de eventos. En el ejemplo de código de este tema se usa un origen de datos muy sencillo para fines ilustrativos. En una configuración de producción, normalmente cargará solo las filas que necesita mostrar en una memoria caché y controlará los eventos DataGridView para interactuar con la memoria caché y actualizarla. Para obtener más información, vea Implementar el modo virtual mediante la carga de datos Just-In-Time en el control DataGridView de formularios Windows Forms
Para copiar el código de este tema como una sola lista, vea Cómo: Implementar el modo virtual en el control DataGridView de formularios Windows Forms.
Crear el formulario
Para implementar el modo virtual
Crear una clase que derive de Form y que contenga un control DataGridView.
El código siguiente contiene algunas inicializaciones básicas. Declara algunas variables que se usarán en pasos posteriores, proporciona un método
Main
y proporciona un diseño de formulario simple en el constructor de clase.#using <System.Drawing.dll> #using <System.dll> #using <System.Windows.Forms.dll> using namespace System; using namespace System::Windows::Forms; public ref class Customer { private: String^ companyNameValue; String^ contactNameValue; public: Customer() { // Leave fields empty. } Customer( String^ companyName, String^ contactName ) { companyNameValue = companyName; contactNameValue = contactName; } property String^ CompanyName { String^ get() { return companyNameValue; } void set( String^ value ) { companyNameValue = value; } } property String^ ContactName { String^ get() { return contactNameValue; } void set( String^ value ) { contactNameValue = value; } } }; public ref class Form1: public Form { private: DataGridView^ dataGridView1; // Declare an ArrayList to serve as the data store. System::Collections::ArrayList^ customers; // Declare a Customer object to store data for a row being edited. 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. int rowInEdit; // Declare a variable to indicate the commit scope. // Set this value to false to use cell-level commit scope. bool rowScopeCommit; public: static void Main() { Application::Run( gcnew Form1 ); } Form1() { dataGridView1 = gcnew DataGridView; customers = gcnew System::Collections::ArrayList; rowInEdit = -1; rowScopeCommit = true; // Initialize the form. this->dataGridView1->Dock = DockStyle::Fill; this->Controls->Add( this->dataGridView1 ); this->Load += gcnew EventHandler( this, &Form1::Form1_Load ); } private:
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)"; }
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
}; int main() { Form1::Main(); }
}
End Class
Implemente un controlador para el evento Load de su formulario que inicialice el control DataGridView y rellene el almacén de datos con valores de ejemplo.
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 += gcnew DataGridViewCellValueEventHandler( this, &Form1::dataGridView1_CellValueNeeded ); this->dataGridView1->CellValuePushed += gcnew DataGridViewCellValueEventHandler( this, &Form1::dataGridView1_CellValuePushed ); this->dataGridView1->NewRowNeeded += gcnew DataGridViewRowEventHandler( this, &Form1::dataGridView1_NewRowNeeded ); this->dataGridView1->RowValidated += gcnew DataGridViewCellEventHandler( this, &Form1::dataGridView1_RowValidated ); this->dataGridView1->RowDirtyStateNeeded += gcnew QuestionEventHandler( this, &Form1::dataGridView1_RowDirtyStateNeeded ); this->dataGridView1->CancelRowEdit += gcnew QuestionEventHandler( this, &Form1::dataGridView1_CancelRowEdit ); this->dataGridView1->UserDeletingRow += gcnew DataGridViewRowCancelEventHandler( this, &Form1::dataGridView1_UserDeletingRow ); // Add columns to the DataGridView. DataGridViewTextBoxColumn^ companyNameColumn = gcnew DataGridViewTextBoxColumn; companyNameColumn->HeaderText = L"Company Name"; companyNameColumn->Name = L"Company Name"; DataGridViewTextBoxColumn^ contactNameColumn = gcnew DataGridViewTextBoxColumn; contactNameColumn->HeaderText = L"Contact Name"; contactNameColumn->Name = L"Contact Name"; this->dataGridView1->Columns->Add( companyNameColumn ); this->dataGridView1->Columns->Add( contactNameColumn ); this->dataGridView1->AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode::DisplayedCells; // Add some sample entries to the data store. this->customers->Add( gcnew Customer( L"Bon app'",L"Laurence Lebihan" ) ); this->customers->Add( gcnew Customer( L"Bottom-Dollar Markets",L"Elizabeth Lincoln" ) ); this->customers->Add( gcnew Customer( L"B's Beverages",L"Victoria Ashworth" ) ); // Set the row count, including the row for new records. this->dataGridView1->RowCount = 4; }
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_CellValueNeeded); this.dataGridView1.CellValuePushed += new DataGridViewCellValueEventHandler(dataGridView1_CellValuePushed); this.dataGridView1.NewRowNeeded += new DataGridViewRowEventHandler(dataGridView1_NewRowNeeded); this.dataGridView1.RowValidated += new DataGridViewCellEventHandler(dataGridView1_RowValidated); this.dataGridView1.RowDirtyStateNeeded += new QuestionEventHandler(dataGridView1_RowDirtyStateNeeded); this.dataGridView1.CancelRowEdit += new QuestionEventHandler(dataGridView1_CancelRowEdit); this.dataGridView1.UserDeletingRow += new DataGridViewRowCancelEventHandler(dataGridView1_UserDeletingRow); // 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.DisplayedCells; // 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")); // Set the row count, including the row for new records. this.dataGridView1.RowCount = 4; }
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.DisplayedCells ' 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
Implemente un controlador para el evento CellValueNeeded que recupera el valor de celda solicitado del almacén de datos o del objeto
Customer
actualmente en edición.Este evento se produce cada vez que el control DataGridView necesita pintar una celda.
void dataGridView1_CellValueNeeded( Object^ /*sender*/, System::Windows::Forms::DataGridViewCellValueEventArgs^ e ) { Customer^ customerTmp = nullptr; // Store a reference to the Customer object for the row being painted. if ( e->RowIndex == rowInEdit ) { customerTmp = this->customerInEdit; } else { customerTmp = dynamic_cast<Customer^>(this->customers[ e->RowIndex ]); } // Set the cell value to paint using the Customer object retrieved. int switchcase = 0; if ( (this->dataGridView1->Columns[ e->ColumnIndex ]->Name)->Equals( L"Company Name" ) ) switchcase = 1; else if ( (this->dataGridView1->Columns[ e->ColumnIndex ]->Name)->Equals( L"Contact Name" ) ) switchcase = 2; switch ( switchcase ) { case 1: e->Value = customerTmp->CompanyName; break; case 2: e->Value = customerTmp->ContactName; break; } }
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; } }
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
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.void dataGridView1_CellValuePushed( Object^ /*sender*/, System::Windows::Forms::DataGridViewCellValueEventArgs^ e ) { Customer^ customerTmp = nullptr; // 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 == nullptr ) { this->customerInEdit = gcnew Customer( (dynamic_cast<Customer^>(this->customers[ e->RowIndex ]))->CompanyName, (dynamic_cast<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. int switchcase = 0; if ( (this->dataGridView1->Columns[ e->ColumnIndex ]->Name)->Equals( L"Company Name" ) ) switchcase = 1; else if ( (this->dataGridView1->Columns[ e->ColumnIndex ]->Name)->Equals( L"Contact Name" ) ) switchcase = 2; switch ( switchcase ) { case 1: customerTmp->CompanyName = dynamic_cast<String^>(e->Value); break; case 2: customerTmp->ContactName = dynamic_cast<String^>(e->Value); break; } }
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. 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; } }
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
Implemente un controlador para el evento NewRowNeeded que crea un nuevo objeto
Customer
que representa una fila recién creada.Este evento se produce cada vez que el usuario escribe la fila para los nuevos registros.
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 = gcnew Customer; this->rowInEdit = this->dataGridView1->Rows->Count - 1; }
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; }
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
Implemente un controlador para el evento RowValidated que guarda filas nuevas o modificadas en el almacén de datos.
Este evento se produce cada vez que el usuario cambia la fila actual.
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 = nullptr; this->rowInEdit = -1; } else if ( this->customerInEdit != nullptr && e->RowIndex < this->customers->Count ) { // Save the modified Customer object in the data store. this->customers[ e->RowIndex ] = this->customerInEdit; this->customerInEdit = nullptr; this->rowInEdit = -1; } else if ( this->dataGridView1->ContainsFocus ) { this->customerInEdit = nullptr; this->rowInEdit = -1; } }
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; } }
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 ' Add the new Customer object to the data store. Me.customers.Add(Me.customerInEdit) Me.customerInEdit = Nothing Me.rowInEdit = -1 ElseIf (Me.customerInEdit IsNot 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
Implemente un controlador para el evento RowDirtyStateNeeded que indica si el evento CancelRowEdit se producirá cuando el usuario señale la reversión de fila presionando ESC dos veces en modo de edición o una vez fuera del modo de edición.
De forma predeterminada, CancelRowEdit se produce tras la reversión de filas cuando se han modificado las celdas de la fila actual a menos que la propiedad QuestionEventArgs.Response esté establecida en
true
en el controlador de eventos RowDirtyStateNeeded. Este evento es útil cuando el ámbito de confirmación se determina en tiempo de ejecución.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; } }
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; } }
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
Implemente un controlador para el evento CancelRowEdit que descarta los valores del objeto
Customer
que representa la fila actual.Este evento se produce cuando el usuario señala la reversión de fila presionando ESC dos veces en modo de edición o una vez fuera del modo de edición. Este evento no se produce si no se han modificado celdas de la fila actual o si el valor de la propiedad QuestionEventArgs.Response se ha establecido en
false
en un controlador de eventos RowDirtyStateNeeded.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 = gcnew Customer; } else { // If the user has canceled the edit of an existing row, // release the corresponding Customer object. this->customerInEdit = nullptr; this->rowInEdit = -1; } }
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; } }
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
Implemente un controlador para el evento UserDeletingRow que elimina un objeto
Customer
existente del almacén de datos o descarta un objetoCustomer
no guardado que representa una fila recién creada.Este evento se produce cada vez que el usuario elimina una fila haciendo clic en un encabezado de fila y presionando la tecla DELETE.
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 = nullptr; } }
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; } }
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
Implemente una clase
Customers
simple para representar los elementos de datos usados por este ejemplo de código.public ref class Customer { private: String^ companyNameValue; String^ contactNameValue; public: Customer() { // Leave fields empty. } Customer( String^ companyName, String^ contactName ) { companyNameValue = companyName; contactNameValue = contactName; } property String^ CompanyName { String^ get() { return companyNameValue; } void set( String^ value ) { companyNameValue = value; } } property String^ ContactName { String^ get() { return contactNameValue; } void set( String^ value ) { contactNameValue = value; } } };
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; } } }
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
Probar la aplicación
Puede comprobar el formulario para asegurarse de que se comporta de la forma prevista.
Para comprobar el formulario
Compile y ejecute la aplicación.
Verá un control DataGridView poblado con tres registros de clientes. Puede modificar los valores de varias celdas de una fila y presionar ESC dos veces en modo de edición y una vez fuera del modo de edición para revertir toda la fila a sus valores originales. Al modificar, agregar o eliminar filas en el control, los objetos
Customer
del almacén de datos también se modifican, agregan o eliminan.
Pasos siguientes
Esta aplicación proporciona un conocimiento básico de los eventos que debe controlar para implementar el modo virtual en el control DataGridView. Puede mejorar esta aplicación básica de varias maneras:
Implemente un almacén de datos que almacene en caché los valores de una base de datos externa. La memoria caché debe recuperar y descartar los valores según sea necesario para que solo contenga lo necesario para mostrar mientras consume una pequeña cantidad de memoria en el equipo cliente.
Ajuste el rendimiento del almacén de datos en función de sus requisitos. Por ejemplo, es posible que desee compensar las conexiones de red lentas en lugar de las limitaciones de memoria del equipo cliente mediante un tamaño de caché mayor y minimizar el número de consultas de base de datos.
Para obtener más información sobre el almacenamiento en caché de valores de una base de datos externa, vea Cómo: Implementar el modo virtual con la carga de datos Just-In-Time en el control DataGridView de formularios Windows Forms.
Vea también
- DataGridView
- VirtualMode
- CellValueNeeded
- CellValuePushed
- NewRowNeeded
- RowValidated
- RowDirtyStateNeeded
- CancelRowEdit
- UserDeletingRow
- Ajuste del rendimiento del control DataGridView en formularios Windows Forms
- 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
- Procedimiento para implementar el modo virtual en el control DataGridView de formularios Windows Forms
.NET Desktop feedback