Практическое руководство. Реализация виртуального режима для элемента управления DataGridView в Windows Forms
Обновлен: Ноябрь 2007
Следующий пример кода демонстрирует управление большими наборами данных при помощи элемента управления DataGridView со свойством VirtualMode равным true.
Полное описание этого примера кода см. в разделе Пример. Реализация виртуального режима для элемента управления DataGridView в Windows Forms.
Пример
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
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
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
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
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
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
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
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
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
End Class
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
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)";
}
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.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"));
// Set the row count, including the row for new records.
this.dataGridView1.RowCount = 4;
}
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 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;
}
}
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 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 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_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 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;
}
}
}
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;
}
}
}
Компиляция кода
Для этого примера необходимо следующее:
- Ссылки на сборки System и System.Windows.Forms.
Дополнительные сведения о построении этого примера из командной строки в среде Visual Basic или Visual C# см. в разделе Построение из командной строки (Visual Basic) или Построение из командной строки с помощью csc.exe. Можно также построить этот пример в Visual Studio путем вставки кода в новый проект. Дополнительные сведения см. в разделах Практическое руководство. Компиляция и выполнение откомпилированного примера кода формы Windows Forms с помощью Visual Studio и Практическое руководство. Компиляция и выполнение откомпилированного примера кода формы Windows Forms с помощью Visual Studio и Практическое руководство. Компиляция и выполнение откомпилированного примера кода формы Windows Forms с помощью Visual Studio.
См. также
Задачи
Пример. Реализация виртуального режима для элемента управления DataGridView в Windows Forms
Основные понятия
Виртуальный режим элемента управления DataGridView в Windows Forms
Ссылки
Другие ресурсы
Оптимизация производительности элемента управления DataGridView в Windows Forms