|
DataGridViewに便利なメソッドを追加するサンプル(VB.NET)

|
<このサンプルの概要>
DataGridViewの派生クラスを作って便利なメソッドを追加して行くと高機能のDataGridViewが出来あがります。
.NETで使用するフレックスグリッド(FlexGrid)の代表的な存在?であるDataGridViewなので、自分だけの便利な
メソッドを追加してライバルに差を付けましょう。(と言うかDataGridViewの標準で実装して欲しいのですが)
このサンプルはDataGridViewの使用方法のサンプルとしてもご使用頂けると思います。
このサンプルは以下の機能を実装しています。
(1)DataGridViewのカラム幅をファイルへ保存/読込するための実装
(2)DataGridViewの各カラムへの入力可能文字を制限するための実装
(3)DataGridViewでCtrl-Vキー押下時にクリップボードから貼り付けるための実装
(4)DataGridViewでDelやBackspaceキー押下時にセルの内容を消去するための実装
今後以下の機能の実装を予定しています。
(1)DataGridViewのコンボボックス(ComboBox)をプルダウン(F4)するための実装
(2)DataGridViewのセルの内容をCSV形式で保存するための実装
★DataGridViewからの派生クラス(DataGridViewPlus.vb)
Imports System.IO
Imports System.Text
Imports System.Xml.Serialization
Imports System.Windows.Forms
Public Class DataGridViewPlus
Inherits System.Windows.Forms.DataGridView
' --------------------------------------------------------------------------------------------
' DataGridViewのカラム幅をファイルへ保存/読込するための実装↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
' --------------------------------------------------------------------------------------------
''' <summary>
''' DataGridViewのカラム幅をXML形式でシリアライズするためのクラス
''' </summary>
''' <remarks></remarks>
Public Class ColWidths
''' <summary>
''' カラム幅s
''' </summary>
Public Widths As Integer()
End Class
''' <summary>
''' DataGridViewのカラム幅をファイルへ保存
''' </summary>
''' <remarks>DataGridViewのカラム幅をXML形式でシリアライズ</remarks>
Public Sub SaveColWidths()
Try
' EXEファイルのPATH
Dim ExePath As String = System.AppDomain.CurrentDomain.BaseDirectory
' XMLファイルのPATH
Dim XmlPath As String = ExePath & "\" & Me.Parent.Name & "_" & Me.Name & ".xml"
' XMLファイルオープン
Dim sw As StreamWriter = New StreamWriter(XmlPath, False, Encoding.Default)
Try
' シリアライザー
Dim serializer As New XmlSerializer(GetType(ColWidths))
' DataGridViewのカラム幅取得
Dim colw As New ColWidths
ReDim colw.Widths(Me.Columns.Count - 1)
For i As Integer = 0 To Me.Columns.Count - 1
colw.Widths(i) = Me.Columns(i).Width
Next
' XMLファイル保存
serializer.Serialize(sw, colw)
Catch ex As Exception
Finally
' XMLファイルクローズ
If sw Is Nothing = False Then sw.Close()
End Try
Catch ex As Exception
End Try
End Sub
''' <summary>
''' DataGridViewのカラム幅を前回保存したファイルから読込
''' </summary>
''' <remarks>DataGridViewのカラム幅をXML形式でデシリアライズ</remarks>
Public Sub ReadColWidths()
Try
' EXEファイルのPATH
Dim ExePath As String = System.AppDomain.CurrentDomain.BaseDirectory
' XMLファイルのPATH
Dim XmlPath As String = ExePath & "\" & Me.Parent.Name & "_" & Me.Name & ".xml"
' XMLファイルオープン
Dim sr As StreamReader = New StreamReader(XmlPath, Encoding.Default)
Try
' シリアライザー
Dim serializer As New XmlSerializer(GetType(ColWidths))
' XMLファイル読込
Dim colw As New ColWidths
colw = CType(serializer.Deserialize(sr), ColWidths)
' DataGridViewにカラム幅設定
For i As Integer = 0 To Me.Columns.Count - 1
Me.Columns(i).Width = colw.Widths(i)
Next
Catch ex As Exception
Finally
' XMLファイルクローズ
If sr Is Nothing = False Then sr.Close()
End Try
Catch ex As Exception
End Try
End Sub
' --------------------------------------------------------------------------------------------
' DataGridViewのカラム幅をファイルへ保存/読込するための実装↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
' --------------------------------------------------------------------------------------------
' --------------------------------------------------------------------------------------------
' DataGridViewの各カラムへの入力可能文字を制限するための実装↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
' --------------------------------------------------------------------------------------------
''' <summary>
''' カラムへの入力可能文字を指定するための配列
''' </summary>
''' <remarks>ColumnChars(0)="1234567890"</remarks>
Public ColumnChars() As String
''' <summary>
''' 編集中のカラム番号
''' </summary>
''' <remarks></remarks>
Private _editingColumn As Integer
''' <summary>
''' 編集中のTextBoxEditingControl
''' </summary>
''' <remarks></remarks>
Private _editingCtrl As DataGridViewTextBoxEditingControl
''' <summary>
''' セルが編集中になった時の処理
''' </summary>
''' <param name="sender">イベントの発生元</param>
''' <param name="e">イベントの情報</param>
''' <remarks>編集中のTextBoxEditingControlにKeyPressイベント設定</remarks>
Private Sub DataGridViewPlus_EditingControlShowing(ByVal sender As Object, _
ByVal e As DataGridViewEditingControlShowingEventArgs) Handles Me.EditingControlShowing
' 編集中のカラム番号を保存
_editingColumn = CType(sender, DataGridView).CurrentCellAddress.X
Try
' 編集中のTextBoxEditingControlにKeyPressイベント設定
_editingCtrl = CType(e.Control, DataGridViewTextBoxEditingControl)
AddHandler _editingCtrl.KeyPress, AddressOf DataGridViewPlus_CellKeyPress
Catch
End Try
End Sub
''' <summary>
''' セルの編集が終わった時の処理
''' </summary>
''' <param name="sender">イベントの発生元</param>
''' <param name="e">イベントの情報</param>
''' <remarks>編集中のTextBoxEditingControlからKeyPressイベント削除</remarks>
Private Sub DataGridViewPlus_CellEndEdit(ByVal sender As Object, _
ByVal e As DataGridViewCellEventArgs) Handles Me.CellEndEdit
If _editingCtrl Is Nothing = False Then
' 編集中のTextBoxEditingControlからKeyPressイベント削除
RemoveHandler _editingCtrl.KeyPress, AddressOf DataGridViewPlus_CellKeyPress
_editingCtrl = Nothing
End If
End Sub
''' <summary>
''' 編集中のTextBoxEditingControlのKeyPressの処理
''' </summary>
''' <param name="sender">イベントの発生元</param>
''' <param name="e">イベントの情報</param>
''' <remarks>力可能文字の判定</remarks>
Private Sub DataGridViewPlus_CellKeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs)
' カラムへの入力可能文字を指定するための配列が指定されているかチェック
If IsArray(ColumnChars) Then
' カラムへの入力可能文字を指定するための配列数チェック
If ColumnChars.GetLength(0) - 1 >= _editingColumn Then
' カラムへの入力可能文字が指定されているかチェック
If ColumnChars(_editingColumn) <> "" Then
' カラムへの入力可能文字かチェック
If InStr(ColumnChars(_editingColumn), e.KeyChar) <= 0 Then
' カラムへの入力可能文字では無いので無効
e.Handled = True
End If
End If
End If
End If
End Sub
' --------------------------------------------------------------------------------------------
' DataGridViewの各カラムへの入力可能文字を制限するための実装↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
' --------------------------------------------------------------------------------------------
' --------------------------------------------------------------------------------------------
' DataGridViewでCtrl-Vキー押下時にクリップボードから貼り付けるための実装↓↓↓↓↓↓↓↓↓↓↓
' DataGridViewでDelやBackspaceキー押下時にセルの内容を消去するための実装↓↓↓↓↓↓↓↓↓↓↓
' --------------------------------------------------------------------------------------------
Private Sub DataGridViewPlus_KeyDown(ByVal sender As Object, _
ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
Dim dgv As DataGridView = CType(sender, DataGridView)
Dim x As Integer = dgv.CurrentCellAddress.X
Dim y As Integer = dgv.CurrentCellAddress.Y
If e.KeyCode = Keys.Delete Or e.KeyCode = Keys.Back Then
' セルの内容を消去
dgv(x, y).Value = ""
ElseIf (e.Modifiers And Keys.Control) = Keys.Control And e.KeyCode = Keys.V Then
' クリップボードの内容を取得
Dim clipText As String = Clipboard.GetText()
' 改行を変換
clipText = clipText.Replace(vbCrLf, vbLf)
clipText = clipText.Replace(vbCr, vbLf)
' 改行で分割
Dim lines() As String = clipText.Split(vbLf)
Dim r As Integer
Dim nflag As Boolean = True
For r = 0 To lines.GetLength(0) - 1
' 最後のNULL行をコピーするかどうか
If r >= lines.GetLength(0) - 1 And _
"".Equals(lines(r)) And nflag = False Then Exit For
If "".Equals(lines(r)) = False Then nflag = False
' タブで分割
Dim vals() As String = lines(r).Split(vbTab)
' 各セルの値を設定
Dim c As Integer = 0
Dim c2 As Integer = 0
For c = 0 To vals.GetLength(0) - 1
' セルが存在しなければ貼り付けない
If Not (x + c2 >= 0 And x + c2 < dgv.ColumnCount And _
y + r >= 0 And y + r < dgv.RowCount) Then
Continue For
End If
' 非表示セルには貼り付けない
If dgv(x + c2, y + r).Visible = False Then
c = c - 1
Continue For
End If
'' 貼り付け処理(入力可能文字チェック無しの時)------------
'' 行追加モード&(最終行の時は行追加)
'If y + r = dgv.RowCount - 1 And _
' dgv.AllowUserToAddRows = True Then
' dgv.RowCount = dgv.RowCount + 1
'End If
'' 貼り付け
'dgv(x + c2, y + r).Value = vals(c)
' ------------------------------------------------------
' 貼り付け処理(入力可能文字チェック有りの時)------------
Dim pststr As String = ""
For i As Long = 0 To vals(c).Length - 1
_editingColumn = x + c2
Dim tmpe As KeyPressEventArgs = _
New KeyPressEventArgs(vals(c).Substring(i, 1))
tmpe.Handled = False
DataGridViewPlus_CellKeyPress(sender, tmpe)
If tmpe.Handled = False Then
pststr = pststr & vals(c).Substring(i, 1)
End If
Next
' 行追加モード&最終行の時は行追加
If y + r = dgv.RowCount - 1 And _
dgv.AllowUserToAddRows = True Then
dgv.RowCount = dgv.RowCount + 1
End If
' 貼り付け
dgv(x + c2, y + r).Value = pststr
' ------------------------------------------------------
' 次のセルへ
c2 = c2 + 1
Next
Next
End If
End Sub
' --------------------------------------------------------------------------------------------
' DataGridViewでCtrl-Vキー押下時にクリップボードから貼り付けるための実装↑↑↑↑↑↑↑↑↑↑↑
' DataGridViewでDelやBackspaceキー押下時にセルの内容を消去するための実装↑↑↑↑↑↑↑↑↑↑↑
' --------------------------------------------------------------------------------------------
End Class
★テスト用フォーム(Form1.vb)
' 予めFrom1にSystem.Windows.Forms.DataGridViewを追加してください。
' そしてForm1.Designer.vbのSystem.Windows.Forms.DataGridViewの部分を
' DataGridViewPlusに変更してください。
Public Class Form1
Private Sub Form1_Load( _
ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' セル選択モード
DataGridView1.SelectionMode = DataGridViewSelectionMode.CellSelect
' 行ヘッダー無し
DataGridView1.RowHeadersVisible = False
' カラムヘッダーは中央表示
DataGridView1.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
' カラムの追加
' TextBoxカラムの追加
DataGridView1.Columns.Add("aaa", "AAA")
DataGridView1.Columns.Add("bbb", "BBB")
'DataGridView1.Columns.Add("ccc", "CCC")
' ComboBoxカラムの追加
Dim cbo As DataGridViewComboBoxColumn = New DataGridViewComboBoxColumn()
cbo.HeaderText = "CCC"
cbo.Name = "ccc"
Dim i As Integer
For i = 1 To 30
cbo.Items.Add("" & i)
Next
DataGridView1.Columns.Add(cbo)
' 各カラムを編集可能に設定
For i = 0 To DataGridView1.Columns.Count - 1
DataGridView1.Columns(i).[ReadOnly] = False
Next
' 行の追加
DataGridView1.Rows.Clear()
DataGridView1.Rows.Add()
DataGridView1.Rows(0).Cells(0).Value = "11"
DataGridView1.Rows(0).Cells(1).Value = "12"
DataGridView1.Rows(0).Cells(2).Value = "13"
DataGridView1.Rows.Add()
DataGridView1.Rows(1).Cells(0).Value = "21"
DataGridView1.Rows(1).Cells(1).Value = "22"
DataGridView1.Rows(1).Cells(2).Value = "23"
' DataGridViewのカラム幅読込
DataGridView1.ReadColWidths()
' DataGridViewの入力可能文字指定
Dim ColumnChars() As String
ReDim ColumnChars(DataGridView1.Columns.Count - 1)
ColumnChars(0) = "abc"
ColumnChars(1) = "123"
ColumnChars(2) = ""
DataGridView1.ColumnChars = ColumnChars
End Sub
Private Sub Form1_FormClosed( _
ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
' DataGridViewのカラム幅保存
DataGridView1.SaveColWidths()
End Sub
End Class
★ちなみに・・・DataGridViewを使用する上でよく使う技
・DataGridViewの指定セルの背景色を変更する方法
DataGridView1.Rows(i).Cells("clmName").Style.BackColor = Color.LightSkyBlue
・DataGridViewに表示する先頭行を変更する方法
DataGridView1.FirstDisplayedScrollingRowIndex = 10
・DataGridViewのカレントセルを取得/変更する方法
Dim v as string = DataGridView1.CurrentCell.Value
DataGridView1.CurrentCell = DataGridView1.Rows(4).Cells("clmName")
・DataGridViewのカレントセルのフォーカスを消す方法
Private Sub DataGridView1_SelectionChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles DataGridView1.SelectionChanged
Dim dgv As DataGridView = sender
dgv.CurrentCell = Nothing
End Sub