|
|||||
<このサンプルの概要> 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形式で保存するための実装 (3)DataGridViewのセルの内容をHTML形式で保存するための実装 (4)DataGridViewのセルの内容をEXCEL形式で保存するための実装 (5)DataGridViewのセルの内容をDB(ACCESS等)に保存するための実装(DBサンプルとの組み合わせ) (6)DataGridViewのセルの内容をDB(ACCESS等)から読込むための実装(DBサンプルとの組み合わせ) ちなみに、このDataGridViewPlusをもっと便利にしているサイトを紹介します。 DataGridViewでコピー&ペーストを可能にする(バインド対応) DataGridView CSV出力(C#/VB.NET) DataGridView CSV読込(C#/VB.NET) DataGridView EXCEL出力(C#/VB.NET) DataGridView EXCEL読込(C#/VB.NET) DataGridView HTML出力(C#/VB.NET) C#.NET版はこちら「DataGridViewに便利なメソッドを追加するサンプル(C#.NET)」です。 また、DataGridViewを使用する上でよく使う技(メモ)は DataGridViewの小技 です。 このサンプルを使用する方法(VB2005の場合)は以下の通りです。 (1)Form1にSystem.Windows.Forms.DataGridViewを追加する (2)Form1.Designer.vbのSystem.Windows.Forms.DataGridViewの部分をDataGridViewPlusに変更する。 (注)VB2010でForm1.Designer.vbの中のソースを表示するには何らかの設定が必要なようです。。。 ★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 AndAlso _ e.KeyChar <> Chr(Keys.Back) 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.Add() ・DataGridViewの行削除方法 DataGridView1.Rows.RemoveAt(0) ・DataGridViewのカラム削除方法(カラムヘッダも削除されます) DataGridView1.Columns.RemoveAt(0) ・DataGridViewの全行削除方法(注意:カラム幅の自動モードで例外が発生する可能性有り) DataGridView.Rows.Clear() ・DataGridViewの指定カラムでソートする方法 DataGridView1.Sort(DataGridView1.Columns(0), ListSortDirection.Ascending) ・DataGridViewの行やカラムを入力禁止(ReadOnly)にする方法 DataGridView1.Rows(0).ReadOnly = True DataGridView1.Columns(0).ReadOnly = True ・DataGridViewの指定セルの背景色を変更する方法 DataGridView1.Rows(i).Cells("clmName").Style.BackColor = Color.LightSkyBlue ・DataGridViewに表示する先頭行(スクロール時の先頭行)を変更する方法 DataGridView1.FirstDisplayedScrollingRowIndex = 10 ・DataGridViewのスクロール範囲でセルが表示されているか確認する方法 If DataGridView1.Rows(4).Cells("clmName").Displayed Then ・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 |