チュートリアル : Windows フォーム DataGridView コントロールでの仮想モードの実装
非常に大きな表形式のデータを DataGridView コントロールに表示するときは、VirtualMode プロパティを true に設定して、コントロールとデータ ストアとのやり取りを明示的に管理できます。 これにより、こうした状況でのコントロールのパフォーマンスを微調整できます。
DataGridView コントロールには、カスタム データ ストアとやり取りするために使用できるイベントが用意されています。 このチュートリアルでは、このようなイベント ハンドラーの実装手順を具体的に示します。 説明しやすくするために、ここで紹介するコード例は非常に単純なデータ ソースを使用しています。 実際のアプリケーションでは、通常は表示に必要な行だけをキャッシュに読み込み、DataGridView イベントを処理して、キャッシュとのやり取りやキャッシュの更新を行います。 詳細については、「Windows フォーム DataGridView コントロールでの Just-In-Time データ読み込みによる仮想モードの実装」を参照してください。
このトピックのコードを単一のリストとしてコピーするには、「方法 : Windows フォーム DataGridView コントロールで仮想モードを実装する」を参照してください。
フォームの作成
仮想モードを実装するには
Form から派生したクラスを作成し、DataGridView コントロールを含めます。
次のコードでは基本的な初期化を行います。 後の手順で使用する変数を宣言し、Main メソッドを定義し、クラス コンストラクターで単純なフォーム レイアウトを作成します。
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
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)"; } ... }
#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: ... }; int main() { Form1::Main(); }
フォームの Load イベントに対して、DataGridView コントロールを初期化し、データ ストアにサンプルの値を格納するためのハンドラーを実装します。
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 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; }
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::AllCells; // 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; }
CellValueNeeded イベントに対して、要求されたセル値をデータ ストアまたは現在編集中の Customer オブジェクトから取得するためのハンドラーを実装します。
このイベントは、DataGridView コントロールがセルを描画しなければならないときに毎回発生します。
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 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; } }
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; } }
CellValuePushed イベントに対して、編集されたセル値を編集中の行を表す Customer オブジェクトに格納するためのハンドラーを実装します。 このイベントは、ユーザーがセル値の変更をコミットすると発生します。
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 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; } }
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; } }
NewRowNeeded イベントに対して、新しく作成される行を表す Customer オブジェクトを作成するためのハンドラーを実装します。
このイベントは、ユーザーが新しいレコード用の行を入力すると発生します。
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 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; }
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; }
RowValidated イベントに対して、新しい行または変更された行をデータ ストアに保存するためのハンドラーを実装します。
このイベントは、ユーザーが現在の行を変更すると発生します。
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 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; } }
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; } }
RowDirtyStateNeeded イベントに対して、ユーザーが Esc キーを (編集モードの場合は 2 回、編集モードでない場合は 1 回) 押して行の復帰を指示したときに CancelRowEdit イベントを発生させるかどうかを設定するハンドラーを実装します。
RowDirtyStateNeeded イベント ハンドラー内で QuestionEventArgs.Response プロパティを true に設定していない場合は、現在行の中の任意のセルが修正されているときに行の復帰を指示すると、既定で CancelRowEdit イベントが発生します。 このイベントは、コミットのスコープが実行時に決定される場合に役立ちます。
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 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; } }
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; } }
CancelRowEdit イベントに対して、現在行を表す Customer オブジェクトの値を破棄するためのハンドラーを実装します。
このイベントは、ユーザーが Esc キーを (編集モードでは 2 回、編集モード以外では 1 回) 押して行の復帰を指示したときに発生します。 このイベントは、現在行の中に変更されたセルがない場合や、RowDirtyStateNeeded イベント ハンドラー内で QuestionEventArgs.Response プロパティの値が false に設定されている場合には発生しません。
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 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; } }
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; } }
UserDeletingRow イベントに対して、既存の Customer オブジェクトをデータ ストアから削除したり、新しく作成された行を表す保存されていない Customer オブジェクトを破棄したりするためのハンドラーを実装します。
このイベントは、ユーザーが行ヘッダーをクリックした後に Del キーを押して行を削除すると発生します。
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
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; } }
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; } }
このコード例で使用されるデータ項目を表す単純な Customers クラスを実装します。
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
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 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; } } };
アプリケーションのテスト
フォームをテストして、期待どおりに動作することを確認します。
フォームをテストするには
アプリケーションをコンパイルして実行します。
3 件の顧客レコードを含んだ DataGridView コントロールが表示されます。 行内の複数のセルの値を変更した後に、Esc キーを (編集モードの場合は 2 回、編集モードでない場合は 1 回) 押すと、行全体を元の値に戻すことができます。 コントロール内の行を変更、追加、または削除すると、データ ストア内の Customer オブジェクトも変更、追加、削除されます。
次の手順
このアプリケーションは、DataGridView コントロールの仮想モードを実装するときに処理しなければならないイベントの基本を示しています。 このアプリケーションはさまざまな方法で改良できます。
外部データベースから値をキャッシュするデータ ストアを実装します。 このキャッシュは必要に応じて値を取得および破棄するので、表示に必要なデータだけを格納し、クライアント コンピューターのメモリ消費量を抑えることができます。
データ ストアのパフォーマンスを要件に合わせて微調整します。 たとえば、クライアント コンピューターのメモリの制限よりも、ネットワーク接続の遅さをカバーするためには、大きなサイズのキャッシュを使用して、データベース クエリの回数を最小限に抑えます。
外部データベースから値をキャッシュする方法の詳細については、「方法 : Windows フォーム DataGridView コントロールで Just-In-Time データ読み込みを使用して仮想モードを実装する」を参照してください。
参照
処理手順
方法 : Windows フォーム DataGridView コントロールで仮想モードを実装する
参照
概念
Windows フォーム DataGridView コントロールを拡張するための推奨される手順
Windows フォーム DataGridView コントロールでの Just-In-Time データ読み込みによる仮想モードの実装