Passo a passo: implementando o modo virtual no controle DataGridView dos Windows Forms
Quando você deseja exibir grandes quantidades de dados tabulares em um DataGridView controle, você pode definir a propriedade true
e gerenciar explicitamente a VirtualMode interação do controle com seu armazenamento de dados. Isso permite ajustar o desempenho do controle nessa situação.
O DataGridView controle fornece vários eventos que você pode manipular para interagir com um armazenamento de dados personalizado. Este passo a passo orienta você ao longo do processo de implementar esses manipuladores de eventos. O exemplo de código neste tópico usa uma fonte de dados muito simples para fins de ilustração. Em uma configuração de produção, você normalmente carregará apenas as linhas necessárias para exibir em um cache e manipulará DataGridView eventos para interagir e atualizar o cache. Para obter mais informações, consulte Implementando o modo virtual com carregamento de dados Just-In-Time no controle DataGridView dos Windows Forms
Para copiar o código deste tópico como uma única lista, consulte Como implementar o modo virtual no controle DataGridView dos Windows Forms.
Criando o formulário
Para implementar o modo virtual
Crie uma classe que deriva de Form e contém um DataGridView controle.
O código a seguir contém uma inicialização básica. Ele declara algumas variáveis que serão usadas em etapas posteriores, fornece um método
Main
e fornece um layout de formulário simples no construtor da classe.#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 um manipulador para o evento do Load formulário que inicializa o controle e preenche o DataGridView armazenamento de dados com valores de exemplo.
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 um manipulador para o evento que recupera o CellValueNeeded valor da célula solicitada do armazenamento de dados ou do
Customer
objeto atualmente em edição.Esse evento ocorre sempre que o DataGridView controle precisa pintar uma célula.
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 um manipulador para o evento que armazena CellValuePushed um valor de célula editado
Customer
no objeto que representa a linha editada. Esse evento ocorre sempre que o usuário confirma uma alteração de valor da célula.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 um manipulador para o NewRowNeeded evento que cria um novo
Customer
objeto que representa uma linha recém-criada.Esse evento ocorre sempre que o usuário insere a linha de novos 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 um manipulador para o RowValidated evento que salva linhas novas ou modificadas no armazenamento de dados.
Esse evento ocorre sempre que o usuário altera a linha atual.
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 um manipulador para o evento que indica se o evento ocorrerá quando o RowDirtyStateNeededCancelRowEdit usuário sinalizar a reversão de linha pressionando ESC duas vezes no modo de edição ou uma fora do modo de edição.
Por padrão, ocorre na reversão de linha quando qualquer célula na linha atual foi modificada, CancelRowEdit a menos que a QuestionEventArgs.Response propriedade esteja definida como
true
no RowDirtyStateNeeded manipulador de eventos. Esse evento é útil quando o escopo da confirmação é determinado em tempo de execução.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 um manipulador para o CancelRowEdit evento que descarta os valores do
Customer
objeto que representa a linha atual.Esse evento ocorre quando o usuário sinaliza a reversão da linha pressionando ESC duas vezes no modo de edição ou uma vez fora do modo de edição. Esse evento não ocorrerá se nenhuma célula na linha atual tiver sido modificada ou se o valor da propriedade tiver sido definido como
false
em um RowDirtyStateNeeded manipulador de QuestionEventArgs.Response eventos.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 um manipulador para o UserDeletingRow evento que exclui um objeto existente
Customer
do armazenamento de dados ou descarta um objeto não salvoCustomer
que representa uma linha recém-criada.Esse evento ocorre sempre que o usuário exclui uma linha clicando em um cabeçalho de linha e pressionando a 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 uma classe
Customers
simples para representar os itens de dados usados por este exemplo 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
Testando o aplicativo
Agora, é possível testar o formulário para garantir que ele se comporta da forma esperada.
Para testar o formulário
Compile e execute o aplicativo.
Você verá um DataGridView controle preenchido com três registros de cliente. É possível modificar os valores de várias células em uma linha e pressionar ESC duas vezes no modo de edição e uma vez fora do modo de edição para reverter a linha inteira para seus valores originais. Quando você modifica, adiciona ou exclui linhas no controle, objetos
Customer
no armazenamento de dados também são modificados, adicionados ou excluídos.
Próximas etapas
Este aplicativo fornece uma compreensão básica dos eventos que você deve manipular para implementar o DataGridView modo virtual no controle. É possível aprimorar esse aplicativo básico de várias maneiras:
Implemente um armazenamento de dados que armazena em cache os valores de um banco de dados externo. O cache deve recuperar e descartar valores conforme necessário, de modo que ele contenha apenas o que é necessário para exibição enquanto consome uma quantidade pequena de memória no computador cliente.
Ajuste o desempenho do armazenamento de dados dependendo de seus requisitos. Por exemplo, talvez você queira compensar conexões de rede lentas em vez de limitações de memória do computador cliente usando um tamanho de cache maior e minimizando o número de consultas ao banco de dados.
Para obter mais informações armazenar em cache valores de um banco de dados externo, consulte Como implementar o modo virtual com carregamento de dados Just-In-Time no controle DataGridView dos Windows Forms.
Confira também
- DataGridView
- VirtualMode
- CellValueNeeded
- CellValuePushed
- NewRowNeeded
- RowValidated
- RowDirtyStateNeeded
- CancelRowEdit
- UserDeletingRow
- Ajuste de desempenho no controle DataGridView do Windows Forms
- Práticas recomendadas para colocação em escala do controle DataGridView dos Windows Forms
- Implementando o modo virtual com carregamento de dados Just-In-Time no controle DataGridView dos Windows Forms
- Como implementar o modo virtual no controle DataGridView dos Windows Forms
.NET Desktop feedback