japan.internet.com The Internet & IT Network


RSSニュース検索
カテゴリ
> トップページ
> Webビジネス
> Eコマース
> Webファイナンス
> Webマーケティング
> パブリック
> Webテクノロジー
> 携帯・ワイヤレス
> Linux Today
> Linux Tutorial
> J.I.C.ブログ
キャリア
> 転職ならen
> 派遣ならen
> アルバイトならen
> IT求人情報
ヘッドライン
> 今日のヘッドライン
> 週間ヘッドライン
Special Link
> フォトコミュニティ
> ストックフォト
> クリップアート
> イラスト
> フェリカ
> Web2.0
> 写真
イベント&セミナー
> イベントカレンダー
> 書評「IT の耳」
> 出張・接待検索
> ニュースガジェット 注目
無料ニュースメール
> 新規登録
> 変更・解除
> オプトインメールの登録・変更・解除
インフォメーション
> パートナーサイト
転職ならエン
就職ならen
求人ならen
履歴書ならen
アルバイトならエン
CRM/SFAならオラクル
> グループ会社
株式会社アエリア
(株)サンゼロミニッツ
株式会社エアネット
> お問い合わせ
> 広告掲載について
> リンクについて
> 著作権について
> その他お問い合わせ
> 利用規約
> 個人情報保護方針
> 会社概要地図
デベロッパー 2007年5月22日 10:00
デベロッパー・バックナンバー
DataGridViewコントロールを操作する101の方法

著者: Wei-Meng Lee  オリジナル版を読む プリンター用 記事を転送
2007年5月22日 10:00 付の記事
海外internet.com発の記事
このエントリーを含むはてなブックマーク この記事をクリップ! Buzzurlにブックマーク Yahoo!ブックマークに登録 newsing it!

はじめに

 Windows Formsプログラミングで普段よく使われるコントロールの一つにDataGridViewがあります。DataGridViewは、Windows Forms 2.0で新たに登場したコントロールで、Windows Forms 1.0のDataGridコントロールの後継となるものです。非常に強力で用途の広いコントロールであり、各種のデータソースを表形式で表示するのに向いています。柔軟性が高いゆえに、公開されているプロパティ、メソッド、イベントも多数にのぼり、初心者にはかなり取っ付きにくいコントロールと言えます。

 本稿は、プログラミングの現場でDataGridViewコントロールをすぐ使いこなせるようにすることを目指しています。一般的なタスクをほぼカバーするよう努めましたが、DataGridViewコントロールの全機能を網羅しているわけではありません。

 本稿では、WindowsアプリケーションプロジェクトのデフォルトのフォームForm1にDataGridViewコントロールを配置するものと仮定します(図1)。

図1 手始めに新規のWindowsアプリケーションプロジェクトを作成し、Form1にDataGridViewコントロールを配置する
図1 手始めに新規のWindowsアプリケーションプロジェクトを作成し、Form1にDataGridViewコントロールを配置する

 それではさまざまなテクニックを見ていきましょう。

配列をバインドする

 DataGridViewコントロールに配列をバインドすることができます。次の例を見てください。

Dim arr() As String = _
   {"Product 1", "Product 24", "Product 356"}
DataGridView1.DataSource = arr

 arr()は3個の要素を持つ文字列配列です。DataSourceプロパティを用いてDataGridViewコントロールにバインドされています。図2に、このデータバインドの結果を示します。

図2 文字列配列をDataGridViewコントロールにバインドした結果
図2 文字列配列をDataGridViewコントロールにバインドした結果

 この結果は意外なものかもしれません。おそらく、配列の各要素が表示されると予想していた人が多いのではないでしょうか。実際には、各要素の長さが表示されます。DataGridViewコントロールはバインドされたオブジェクトの最初のパブリックプロパティを探すからです。この例では、文字列配列の最初のパブリックプロパティは配列内の各要素の長さなので、上のような結果が得られるわけです。

 文字列配列をDataGridViewコントロールに正しくバインドするためには、次に示すように文字列型をラップするクラスを作成し、このクラスが、要素の内容を返すパブリックプロパティNameを公開するようにします。

Public Class CStringItem
    Private _str As String
    Public Sub New(ByVal str As String)
        _str = str
    End Sub

    Public Property Name() As String
        Get
            Return _str
        End Get

        Set(ByVal value As String)
            _str = value
        End Set
    End Property

End Class

 次の例では、arr()をCStringItem型の配列として宣言し、3個の要素を初期設定した後で、DataGridViewコントロールにバインドします。

’---modified array---
Dim arr() As CStringItem = { _
   New CStringItem("Product 1"), _
   New CStringItem("Product 2"), _
   New CStringItem("Product 3")}
DataGridView1.DataSource = arr

 図3は、このデータバインドの結果です。パブリックプロパティNameがDataGridViewコントロール内の列の見出しテキストとして使われていることに注意してください。

図3 DataGridViewコントロールにオブジェクトの配列をバインドした結果
図3 DataGridViewコントロールにオブジェクトの配列をバインドした結果

カスタムオブジェクトをバインドする

 次の例では、DataGridViewコントロールにもっと複雑なオブジェクトをバインドする方法を説明します。2つのパブリックプロパティ(NameID)を持つCStudentクラスを定義します。

Public Class CStudent
    Private _name As String
Private _ID As String

    Public Sub New(ByVal id As String, ByVal name As String)
        _ID = id
        _name = name
    End Sub

    Public Property Name() As String
        Get
            Return _name
        End Get

        Set(ByVal value As String)
            _name = value
        End Set
    End Property

    Public Property ID() As String
        Get
            Return _ID
        End Get

        Set(ByVal value As String)
            _ID = value
        End Set
    End Property

End Class

 DataGridViewコントロールにCStudentオブジェクトの配列をバインドすると、図4の結果が得られます。

’---binding to custom object---
Dim students() As CStudent = _
   {New CStudent("123-456-789", "John"), _
    New CStudent("456-123-789", "Mary")}
DataGridView1.DataSource = students

図4 DataGridViewコントロールにCStudentオブジェクトの配列をバインドした結果
図4 DataGridViewコントロールにCStudentオブジェクトの配列をバインドした結果

型指定されたデータセットを用いてバインドする

 DataGridViewコントロールが特によく使われるのは、データベースのテーブルをバインドするケースです。これを説明するために、現在のプロジェクトに型指定されたデータセットを追加します。Visual Studio 2005のソリューションエクスプローラでプロジェクト名を右クリックし、[追加]→[新しい項目の追加]を選択します。データセットテンプレートを選択し(DataSet1.xsdのデフォルトの名前を使用)、[追加]をクリックします。

 サーバエクスプローラを起動し([表示]→[サーバエクスプローラ])、「Northwind」サンプルデータベースに移動します(SQL Server/SQL Server Expressでインストールされているものと仮定)。「Customers」テーブルをDataSet1.xsdのデザインサーフェイスにドラッグ&ドロップします。図5は、型指定されたデータセットを作成する様子を示しています。

図5 型指定されたデータセットを作成する
図5 型指定されたデータセットを作成する

 次のステップには2つの選択肢があります。1つは、次に示すようにDataGridViewコントロールに「Customers」テーブルのテーブルアダプタを直接バインドする方法です。

’---create an instance of the table adapter---
Dim adapter As New CustomersTableAdapter

’---data bind to the DataGridView control---

DataGridView1.DataSource = adapter.GetData

 もう1つは、BindingSourceコントロールを使用する方法です。

’---create an instance of the table adapter---
Dim adapter As New CustomersTableAdapter


’---create an instance of the bindingsource control---
Dim bindingSrc As New BindingSource

’---set the datasource for the bindingsource control---
bindingSrc.DataSource = adapter.GetData

’---data bind to the DataGridView control---
DataGridView1.DataSource = bindingSrc

 なお、上のコードが正常に実行されるようにするためには、次のように名前空間をインポートしておく必要があります(DVGは、このプロジェクトの名前です)。

Imports DGV.DataSet1TableAdapters

 図6は、このデータバインドの結果です。

図6 型指定されたデータセットをバインドした結果
図6 型指定されたデータセットをバインドした結果

データセットでバインドする

 データセットを手動で作成する場合は、DataSourceプロパティにデータセットを設定し、表示するテーブルをDataMemberプロパティに指定すれば、DataGridViewコントロールにバインドできます。

Dim connStr As String = _
    "Data Source=.SQLEXPRESS;Initial Catalog=Northwind;" & _
    "Integrated Security=True"

Dim sql As String = "SELECT * FROM Customers"
Dim conn As SqlConnection = New SqlConnection(connStr)

Dim comm As SqlCommand = New SqlCommand(sql, conn)
Dim dataadapter As SqlDataAdapter = New SqlDataAdapter(comm)

Dim ds As DataSet = New DataSet()

’---open the connection and fill the dataset---
conn.Open()

’---fill the dataset---
dataadapter.Fill(ds, "Customers_table")


’---close the connection---
conn.Close()

’---bind to the DataGridView control---
DataGridView1.DataSource = ds

’---set the table in the dataset to display---
DataGridView1.DataMember = "Customers_table"

クリックされたセルを検出する

 ユーザーのクリックしたDataGridViewコントロール内のセルの値を取得する場合は、CellEnterイベントを処理します。

’---when the user clicks on the datagridview control---
Private Sub DataGridView1_CellEnter( _
   ByVal sender As Object, _
   ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) _
   Handles DataGridView1.CellEnter
    ’---prints the content of the cell---

    Console.WriteLine( _
       DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value)
End Sub

 RowIndexプロパティとColumnIndexプロパティに、現在選択されているセルの行番号と列番号がそれぞれ設定されます。

DataViewでフィルタリングする

 DataGridViewコントロールに表示されるデータにフィルタをかけるにはDataViewオブジェクトを使用します。

’---create an instance of the table adapter---
Dim adapter As New CustomersTableAdapter


’---create an instance of the dataview class---
Dim dv As New DataView(adapter.GetData)
With dv
    .AllowNew = False
    .AllowDelete = True

    .Sort = "ContactTitle ASC, Address ASC"
    .RowFilter = "CustomerID LIKE ’B*’"
End With
DataGridView1.DataSource = dv

 上の例は、DataViewオブジェクトを使うことにより、DataGridViewコントロールにユーザーが新しい行を追加するのを許可したり(AllowNewプロパティ)、行を削除するのを許可したり(AllowDeleteプロパティ)できることを示しています。また、フィールドとソート順序を指定して行をソートすることもできます(Sortプロパティ)。さらに、SQLに似た式を指定してレコードにフィルタをかけることもできます(RowFilterプロパティ)。

 上の例では、行をContactTitleフィールドの昇順でソートし、さらにAddressフィールドの昇順でソートしています。Addressフィールドの降順でソートする場合は、次のように設定します。

.Sort = "ContactTitle ASC, Address DESC"

 図7に、ContactTitleフィールドとAddressフィールドを共に昇順でソートしたケースと、ContactTitleを昇順、Addressを降順でソートしたケースを示します。

図7 ContactTitleとAddressのソート順序による違い
図7 ContactTitleとAddressのソート順序による違い

列をソートする

 DataViewオブジェクトを使えばフィルタリングやソートを実行できますが、DataGridViewコントロールのSort()メソッドでもソートを制御できます。

’---sort based on the first column---
DataGridView1.Sort(DataGridView1.Columns(0), _
   System.ComponentModel.ListSortDirection.Descending)

 この例では、行を最初の列の降順でソートしています(図8)。

図8 最初の列を降順でソートする
図8 最初の列を降順でソートする

 プログラムによるソートとは別に、ユーザーが実行時にソートグリフ(列見出しの隣に表示される三角形のアイコン)をクリックして行を昇順または降順にソートすることも可能です。行がソートされないようにするには、SortModeプロパティを「NotSortable」に設定します。

’---set the sort mode for a column---
DataGridView1.Columns(1).SortMode = _
   DataGridViewColumnSortMode.NotSortable

プログラミングによって列を追加する

 これまで紹介した方法は、データセットまたはBindingSourceコントロールを用いて、DataGridViewコントロールにデータベースをバインドするというものでした。しかし、ときにはプログラミングによってDataGridViewコントロール内にさまざまなフィールドを作成し、ユーザーに値を設定させる場合もあります(同様に、プログラミングによって新しい行を追加することもできます)。DataGridViewコントロール内に列を作成するには、DataGridViewコントロールのColumnsプロパティのAdd()メソッドを使用します。次の例では、DataGridViewコントロール内に4つのフィールドを作成しています。

’---adding columns---
DataGridView1.Columns.Add("ID", "Product ID")
DataGridView1.Columns.Add("Name", "Product Name")
DataGridView1.Columns.Add("Description", "Description")
DataGridView1.Columns.Add("Price", "Price")

 図9は、このDataGridViewコントロールの表示結果です。

図9 DataGridViewコントロールに4つのフィールドを作成する
図9 DataGridViewコントロールに4つのフィールドを作成する

行を追加する

 DataGridViewコントロールに行を追加するには、RowsプロパティのAdd()メソッドを使用します。

’---add an empty row---
DataGridView1.Rows.Add()

 行を追加してそこに内容を割り当てるには、DataGridViewRowクラスのインスタンスを作成してからCreateCells()メソッドで行テンプレートを作成します。

For i As Integer = 0 To 9
    ’---create a row---

    Dim item As New DataGridViewRow
    item.CreateCells(DataGridView1)
    With item
        .Cells(0).Value = i
        .Cells(1).Value = "Product " & i
        .Cells(2).Value = "Description of Product " & i
        .Cells(3).Value = "99.99"

    End With
    ’---add the row---
    DataGridView1.Rows.Add(item)
Next

 行の各フィールドに割り当てる一連の値を配列に格納し、その配列を使用して新しい行を追加することもできます。

For i As Integer = 0 To 9
    DataGridView1.Rows.Add(New String() _
       {i, _
        "Product " & _
        i, _
        "Description of Product " & i, _
        "99.99"})

Next

 図10は、上の2つの例の出力です。

図10 プログラミングによってDataGridViewコントロールに新しい行を追加する
図10 プログラミングによってDataGridViewコントロールに新しい行を追加する

セルにコンボボックスを表示する

 セルにテキストを表示するだけでなく、ドロップダウンリストボックスを表示して、あらかじめ決められた値をリストから選択できるようにしたいことがあります。その場合は、目的の列のセルにコンボボックスを追加する必要があります。次の例では、DataGridViewコントロールの5番目の列にComboBoxコントロールを追加しています。

’---add columns to the DataGridView control---
DataGridView1.Columns.Add("ID", "Product ID")
DataGridView1.Columns.Add("Name", "Product Name")
DataGridView1.Columns.Add("Description", "Description")
DataGridView1.Columns.Add("Price", "Price")


’---create a new bindingsource control---
Dim bindingsource As New BindingSource

’---add the items into the control---
bindingsource.Add("Type A")
bindingsource.Add("Type B")
bindingsource.Add("Type C")


’---create a combobox column---
Dim comboBoxCol As New DataGridViewComboBoxColumn

’---set the header---
comboBoxCol.HeaderText = "Types"

’---data bind it---

comboBoxCol.DataSource = bindingsource

’---add a combobox column to the DataGridView control---
DataGridView1.Columns.Add(comboBoxCol)

 この出力結果を図11に示します。

図11 DataGridViewのセルにComboBoxを追加する
図11 DataGridViewのセルにComboBoxを追加する

 上の例では、項目リストを含んだBindingSourceコントロールを、DataGridViewコントロール内のDataGridViewComboBoxColumnコントロールにバインドする方法を示しましたが、DataGridViewComboBoxColumnコントロールに項目を直接追加する方法もあります。

’---adding columns---

DataGridView1.Columns.Add("ID", "Product ID")
DataGridView1.Columns.Add("Name", "Product Name")
DataGridView1.Columns.Add("Description", "Description")
DataGridView1.Columns.Add("Price", "Price")


’---add a combobox column---
Dim comboBoxCol As New DataGridViewComboBoxColumn

’---set the header text---
comboBoxCol.HeaderText = "Types"

’---add items to it---

comboBoxCol.Items.Add("Type A")
comboBoxCol.Items.Add("Type B")
comboBoxCol.Items.Add("Type C")

DataGridView1.Columns.Add(comboBoxCol)

 後者の方がより柔軟であり、この方法で実装していると、実行時にユーザーがドロップダウンリストに新しい項目を追加できます(詳細については次のセクションを参照)。ComboBoxコントロールにデータソースをバインドすると、新しい項目を実行時に追加できなくなります。

DataGridViewComboBoxColumnコントロールに項目を追加する

 前のセクションでは、DataGridViewコントロール内のセルにComboBoxコントロールを表示する方法を示しました。ComboBoxコントロールにユーザーが新しい項目を挿入できるようにしたいことがあります。そのためには、少し準備が必要です。

 まず、DataGridViewコントロールのEditingControlShowingイベントを処理します。このイベントは、ユーザーがComboBoxコントロールを編集しようとしたときに発生します。

Private Sub DataGridView1_EditingControlShowing( _
   ByVal sender As Object, _
   ByVal e As System.Windows.Forms. _
      DataGridViewEditingControlShowingEventArgs) _
   Handles DataGridView1.EditingControlShowing

    Dim comboBoxColumn As DataGridViewComboBoxColumn = _
       DataGridView1.Columns(4)
    If (DataGridView1.CurrentCellAddress.X = _
       comboBoxColumn.DisplayIndex) Then

        Dim cb As ComboBox = e.Control
        If (cb IsNot Nothing) Then
            cb.DropDownStyle = ComboBoxStyle.DropDown
        End If

    End If
End Sub

 ここでのポイントは、編集対象のセルがComboBoxを含むセルかどうかを確認することです。ComboBoxを含んでいる場合は、ComboBoxコントロールのドロップダウンスタイルを「DropDown」に設定して、ユーザーによる追加入力ができるようにします。

 次に、DataGridViewコントロールのCellValidatingイベントを処理します。このイベントはユーザーが入力を終了してセルを離れたときに発生します。

Private Sub DataGridView1_CellValidating( _
   ByVal sender As Object, _
   ByVal e As System.Windows.Forms. _
   DataGridViewCellValidatingEventArgs) _
   Handles DataGridView1.CellValidating

    Dim comboBoxColumn As DataGridViewComboBoxColumn = _
       DataGridView1.Columns(4)
    If (e.ColumnIndex = comboBoxColumn.DisplayIndex) Then

        If (Not comboBoxColumn.Items.Contains( _
           e.FormattedValue)) Then
            comboBoxColumn.Items.Add(e.FormattedValue)
        End If
    End If

End Sub

 ここでは、通常のチェックを行った後に、新しく入力された項目をComboBoxに追加します。図12を見ると、ComboBoxには最初3個の項目があります。ここにユーザーが新しい項目(例えば、「Type D」)を入力でき、それがリストに追加されます。実際に操作した行より前または後ろの行でも、ComboBoxコントロールの項目数が4になることに注意してください。

図12 ユーザーが新しい項目をComboBoxコントロールに追加できる
図12 ユーザーが新しい項目をComboBoxコントロールに追加できる

行/列をロックする

 行のReadOnlyプロパティをTrueに設定すると、特定の行が変更されないようにロックできます。

’---first row is readonly---
DataGridView1.Rows(0).ReadOnly = True

 同様に、特定の列に属するセルをロックすることもできます。

’---first column is readonly---
DataGridView1.Columns(0).ReadOnly = True

 ReadOnlyプロパティをTrueに設定するとセルの値は変更されなくなりますが、行の削除ができなくなるわけではありません。

 必要ならDataGridViewコントロール全体をロックすることもできます。

’---entire grid is readonly---
DataGridView1.ReadOnly = True

列を非表示にする

 実行時に列のVisibleプロパティをFalseに設定することで、特定の列を非表示にできます。

’---hides the second column---
DataGridView1.Columns(1).Visible = False

 図13に、列を非表示にしたDataGridViewの例を示します。奥はすべての列を表示した状態で、手前は2番目の列(CompanyName列)を非表示にした状態です。

図13 列を非表示にする前と後のDataGridView
図13 列を非表示にする前と後のDataGridView

ユーザーの編集を検証する

 DataGridViewコントロールの一般的な用途の1つはデータ入力です。ユーザーはコントロールの個々のセルにデータを入力します。そのため、正しい種類のデータが入力されたかどうかを検証することが重要です。

 入力されたデータの種類が正しいことを検証するには、2つのイベントを処理する必要があります。最初にCellValidatingイベントを処理します。このイベントは、ユーザーがセルの値を変更してセルを離れたときに発生します。

Private Sub DataGridView1_CellValidating( _
   ByVal sender As Object, _
   ByVal e As System.Windows.Forms. _
   DataGridViewCellValidatingEventArgs) _
   Handles DataGridView1.CellValidating

    ’---Price field---

    If e.ColumnIndex = 3 Then
       If Not IsNumeric(e.FormattedValue) Then
            DataGridView1.Rows(e.RowIndex).ErrorText = _
               "Price must be a numeric value."

            e.Cancel = True
        End If
    End If
End Sub

 このイベント内で必要な検証を行います。例えば上の例では、4番目の列(列インデックスのPriceフィールド)に数値以外が含まれていないことを確認します。数値以外が含まれている場合は、DataGridViewコントロールの一番左の列にエラーメッセージを表示します(ErrorTextプロパティ)。図14に例を示します。

図14 この画面のコントロールは、セルの値を検証し、左側の列にエラーメッセージを表示する
図14 この画面のコントロールは、セルの値を検証し、左側の列にエラーメッセージを表示する

 ユーザーはエラーを訂正しないと他のセルに移動できません。訂正データが入力されたときにエラーメッセージが消えるようにするには、CellEndEditイベントを処理します。

Private Sub DataGridView1_CellEndEdit( _
   ByVal sender As Object, _
   ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) _
   Handles DataGridView1.CellEndEdit

    ’---clear the error message---

    DataGridView1.Rows(e.RowIndex).ErrorText = String.Empty
End Sub

入力を制限する

 前のセクションでは、ユーザーの入力したセルの値を検証する方法を示しました。しかし、状況によっては、これでもまだ十分でありません。最初から不正な文字が入力されないようにした方が良いこともあります。これは、前のセクションの例で考えると、Priceフィールドに数字以外の文字が入力されないようにすることを意味します。普通のTextBoxコントロールでは、この問題はKeyPressイベントを処理することで解決できます。しかし、この方法をDataGridViewコントロールに適用するためには少し準備が必要です。

 まず、EditingControlShowingイベントを処理します。このイベントはユーザーがセルの内容を編集しようとしたときに発生します。

Private Sub DataGridView1_EditingControlShowing( _
   ByVal sender As Object, _
   ByVal e As System.Windows.Forms. _
   DataGridViewEditingControlShowingEventArgs) _
   Handles DataGridView1.EditingControlShowing

    ’---restrict inputs on the fourth field---

    If Me.DataGridView1.CurrentCell.ColumnIndex = 3 And _
       Not e.Control Is Nothing Then

        Dim tb As TextBox = CType(e.Control, TextBox)

        ’---add an event handler to the TextBox control---
        AddHandler tb.KeyPress, AddressOf TextBox_KeyPress
    End If

End Sub

 ここでは、制限したいTextBoxコントロールにKeyPressイベントハンドラを追加します。このKeyPressイベントハンドラは、ユーザーがセルに入力を行ったときに呼び出されます。この定義は次のとおりです。

Private Sub TextBox_KeyPress( _
   ByVal sender As System.Object, _
   ByVal e As System.Windows.Forms.KeyPressEventArgs)

    ’---if textbox is empty and user pressed a decimal char---

    If CType(sender, TextBox).Text = String.Empty And _
       e.KeyChar = Chr(46) Then
        e.Handled = True
        Return

    End If
    ’---if textbox already has a decimal point---
    If CType(sender, TextBox).Text.Contains(Chr(46)) And _
       e.KeyChar = Chr(46) Then

        e.Handled = True
        Return
    End If
    ’---if the key pressed is not a valid decimal number---
    If (Not (Char.IsDigit(e.KeyChar) Or _
       Char.IsControl(e.KeyChar) Or _
       (e.KeyChar = Chr(46)))) Then

        e.Handled = True
    End If
End Sub

 上記のコードは、ユーザーの入力を数字(「.」も含む)にのみ制限します。それ以外の文字が入力されてもセルには現れません。

行を削除する

 プログラミングによってDataGridViewコントロール内の行を削除するには、Remove()メソッドを使います。次のコードはDataGridViewコントロール内の選択された行をすべて削除します。

For Each row As DataGridViewRow In DataGridView1.SelectedRows
    DataGridView1.Rows.Remove(row)

Next

 ユーザーは最初に行を選択して[Delete]キーを押す方法でも行を削除できます。デフォルトで、この削除は確認なしに自動で実行されます。しかし、削除の前にユーザーに確認を求めることもできます。これにはUserDeletingRowイベントを使います。

Private Sub DataGridView1_UserDeletingRow( _
   ByVal sender As Object, _
   ByVal e As System.Windows.Forms. _
   DataGridViewRowCancelEventArgs) _
   Handles DataGridView1.UserDeletingRow
    If (Not e.Row.IsNewRow) Then

        Dim response As DialogResult = _
        MessageBox.Show( _
        "Are you sure you want to delete this row?", _
        "Delete row?", _
        MessageBoxButtons.YesNo, _
        MessageBoxIcon.Question, _
        MessageBoxDefaultButton.Button2)
        If (response = DialogResult.No) Then
            e.Cancel = True

        End If
    End If
End Sub

 このコードにより、行の削除を実行してよいかを確認するプロンプトが表示されます(図15)。

図15 UserDeletingRowイベントでユーザーに確認を求めてから実際の削除を行う
図15 UserDeletingRowイベントでユーザーに確認を求めてから実際の削除を行う

変更を保存する

 DataGridViewコントロールにデータベースのデータソースをバインドした場合、DataGridViewコントロールにおけるすべての変更がデータベースに自動的に反映されるわけではありません。そのため、すべての変更を手動でデータベースに戻す必要があります。

 以前紹介した、DataGridViewコントロールにデータセットをバインドする例をもう一度考えます。次のコードは、データセットに「Customers」テーブルを読み込みます。

Dim connStr As String = _
    "Data Source=.SQLEXPRESS;Initial Catalog=Northwind;" & _
    "Integrated Security=True"

Dim sql As String = "SELECT * FROM Customers"
Dim conn As SqlConnection = New SqlConnection(connStr)

Dim comm As SqlCommand = New SqlCommand(Sql, conn)
Dim dataadapter As SqlDataAdapter = New SqlDataAdapter(comm)

Dim ds As DataSet = New DataSet()

   ’---open the connection and fill the dataset---
    conn.Open()
    dataadapter.Fill(ds, "Customers_table")
    conn.Close()
    DataGridView1.DataSource = ds
    DataGridView1.DataMember = "Customers_table"

 DataGridViewコントロールでの変更をデータベースに戻すには、次のようにします。

Dim sqlCmdBuilder As New SqlCommandBuilder(dataadapter)
sqlCmdBuilder.GetUpdateCommand()
dataadapter.Update(ds.Tables("Customers_table"))

 SqlCommandBuilderオブジェクトのGetUpdateCommand()メソッドによって、DataGridViewコントロールの変更を反映するSQLステートメントを自動的に作成します。その後、SqlDataAdapterオブジェクトにデータベース内のテーブルを更新させます。

 型指定されたデータセットがDataGridViewコントロールに以下のような方法でバインドされている場合、

Dim adapter As New CustomersTableAdapter

Dim bindingSrc As New BindingSource

    bindingSrc.DataSource = adapter.GetData
    DataGridView1.DataSource = bindingSrc

 次のコードで変更をデータベースに簡単に反映させることができます。

bindingSrc.EndEdit()
adapter.Update(bindingSrc.DataSource)

 変更が文字列などに保存されている場合は、DataGridViewコントロール内のすべての行と列をループで処理します。

Dim output As String = String.Empty
For Each row As DataGridViewRow In DataGridView1.Rows
    For Each cell As DataGridViewCell In row.Cells
        output += cell.Value & ":"

    Next
    output += vbCrLf
Next
MsgBox(output)

おわりに

 本稿では、DataGridViewコントロール関連の一般的なタスクをどのように実行すればよいかを考察しました。DataGridViewは非常に用途の広いコントロールです。本稿が、DataGridViewを使用してデータベースやその他のデータソースを表示しようと考えているプログラマのリファレンスとして役立てば幸いです。

著者紹介

Wei-Meng Lee(Wei-Meng Lee)
Microsoft MVP受賞者。Microsoft社の最新テクノロジー実地研修を専門とするDeveloper Learning Solutions社を創設。.NETとワイヤレステクノロジーの開発者、指導者として知られる。
国際的なカンファレンスでたびたび講演し、.NET、XML、ワイヤレステクノロジーに関する著書、共著書多数。.NETからMac OS Xに至るまで広範な分野について執筆している。著書に『.NET Compact Framework Pocket Guide』 (Oreilly&Associates Inc、2005年5月)、『ASP.NET 2.0: A Developer’s Notebook』 (Oreilly&Associates Inc、2005年6月)、『Programming Sudoku』 (Apress刊、2006年3月)など。ブログ「Wei-Meng Lee’s Blog」を開設している。


関連記事
  • .NETでのテキスト処理技法をマスターする
  • Windowsフォームの入力チェックを効率化する
  • Microsoft AJAX Libraryでドラッグ&ドロップ対応のWebページを作成する
  • ASP.NET 2.0を使ってCSS対応のWebサイトを作成する
  • .NET データ処理に役立つ26のヒント(後編)


  • 関連テーマ
  • フィルタリング
  • XML
  • SQL Server
  • Microsoft
  • Blog


  • ★最新トップニュース
    コラム IT を変えつつあるのはどの技術?(Webビジネス 8月29日 13:30)
    IT マネジャーと企業幹部の間で、IT を最も大胆に変えつつある技術トレンドを巡って意見の相違があるのは当然だ。これら両陣営は敵対関係にある場合が多いため、両者が今日の技術トレンドを違った角度から見ているのは予想できる。
    国内 CTC、日本 HP、マイクロソフト、Hyper-V ベースの仮想化ソリューションを今秋提供へ(Webテクノロジー 8月29日 13:30)
    伊藤忠テクノソリューションズ(CTC)、日本ヒューレット・パッカード(日本 HP)、マイクロソフトの3社は、2008年8月27日、日本 HP とマイクロソフトのサーバー製品・仮想化技術などを組み合わせ、ソリューション検証を共同で実施する、と発表した。
    海外 Facebook 誕生のいきさつが映画に(Webマーケティング 8月29日 13:20)
    ハリウッドの著名脚本家 Aaron Sorkin 氏が、Facebook に自分のページを開設した。Sony Pictures から依頼を受け、Facebook 誕生物語の映画脚本を書くためという。
    海外 価格競争の影響が出た第2四半期のサーバー売上(Webビジネス 8月29日 13:10)
    IDC が、2008年第2四半期のサーバー市場調査を発表した。売上を得るためにベンダー各社が大幅に値下げしている状況がうかがえる内容だ。
    国内 レッドハット、コンサルもパッケージした低価格の SOA 導入支援サービスを開始(LinuxToday 8月29日 13:10)
    SOA 導入初期段階に必要なコンサルテーションサービスと、ユーザーの状況に合わせて独自に設計する技術者向けのトレーニングをセットにしたもの。JBoss Enterprise SOA Platform ユーザーを対象にしたもの。
    トピックス
    > オススメのIT系求人情報【毎週月曜日更新】
    footer_301.gif


    リサーチ
    > デイリーリサーチDLサイト
    > OnlineResearchPortal (リサーチデータバンク)
    > モバイルリサーチ with goo
    footer_301.gif
    キーワード
    > iPhone > Youtube
    > Google > モバイルノート
    > 半導体 > ウィルコム
    > テーマ一覧はこちら
    footer_301.gif
    セミナー情報
    > 第2回インターネットコムマーケティングセミナー
    「モバイルマーケティングの世界」〜これだけはやっておきたいモバイルマーケティング施策とは〜
    9月24日(水)13:00〜17:00 ITS 山王健保会館
    ※詳しくはこちら
    footer_301.gif
    デベロッパー
    > DevX
    > CodeGuru
    > developer.com
    footer_301.gif
    j.i.c.ブログ
    ブログ一覧
    ベンチャー専門家の目利きブログ「なぜこの企業は伸びるのか?」 【ベンチャー専門家の目利きブログ「なぜこの企業は伸びるのか?」】
    「選択と集中」選択をして集中しない限りは勝てない/メディカル・コミュニケーションズ株式会社(8月29日)
    データメーション 【データメーション】
    Apple は顧客の忠誠心にあぐらをかいているのか? (8月27日)
    Graphic Design Forum 【Graphic Design Forum】
    次へとつながる輪 (8月27日)
    最新テクノロジーの意外な処方箋 【最新テクノロジーの意外な処方箋】
    あなたが舌なめずりしたくなるようなもの(8月26日)
    エンジニアの独り言 【エンジニアの独り言】
    データをローカルに保存するWebアプリケーション(8月22日)
    デスマーチからの脱却 【デスマーチからの脱却】
    30min. iPhoneアプリリリース(8月18日)
    footer_301.gif
    最新コラム一覧
    IT マネジメント IT マネジメント

    IT を変えつつあるのはどの技術?(8月29日)
    最新ハイテク講座 最新ハイテク講座

    繁栄か滅亡か!巨大なエネルギー「原子力」の未来(8月29日)
    developer.com developer.com

    レガシーWebアプリケーションをWebLogic Portal内のフルページIFrameとして統合する(8月29日)
    百式のネットビジネス研究 百式のネットビジネス研究

    友達にあなた特製のクスリを贈ることができる「Get Your Drug On」(8月29日)
    週刊-サイト別アクセス状況データ 週刊-サイト別アクセス状況データ

    ビデオリサーチインタラクティブ調査(月間インターネットオーディエンスデータ)(8月28日)
    「IT の耳」 「IT の耳」

    【書評】『1回の会議・打ち合わせで必ず結論を出す技術』――無意味な会議を撲滅する(8月28日)
    ハードウェアから見たデータベース ハードウェアから見たデータベース

    巨大テーブル活用術1(8月28日)
    ウチのサイトを SEO ウチのサイトを SEO

    検索エンジンが見ている世界(8月27日)
    エンジニア転職ノウハウ開発室 エンジニア転職ノウハウ開発室

    目指せecoエンジニア!グリーンITで地球を救え(8月26日)
    アイレップの SEM フロンティア アイレップの SEM フロンティア

    円滑に SEO を導入・実施するための組織体制を構築しよう(3)(8月26日)
    footer_301.gif
    専門チャンネル
    > セキュリティチャネル > テレコムチャネル
    > サーチエンジンウォッチ
    footer_301.gif
    海外のインターネットコム アメリカ韓国ドイツトルコ
    関連企業のサイト:ストックフォト イラスト ネットストリート ホテル予約サイト タウン情報 出張 事業継承 シミュレーション トランクルーム 優待映画チケット 田舎暮らしガイド オリジナルデザインTシャツ ニタコエ
    Copyright 2008 Jupitermedia Corporation All Rights Reserved. http://www.internet.com/
    space.gif space.gif