フォルダツリービュー(3)

VB SampleFolderTreeView 3 : Events & Menu
 フォルダツリービューの三回目です。イベント処理とフォルダの追加・削除等に関する関数群です。なお、今回の記述はすべて FolderTree クラス内に行います。
【INDEX】
ページ1 : フォームとアイテムクラス
ページ2 : ドライブとフォルダの表示
●ページ3 : イベント処理とフォルダ操作
イベントの処理 ... ユーザー操作に対応するイベント処理
フォルダの操作 ... フォルダの作成・削除・リネーム(名前の編集)

■イベントの処理
 各コントロールのイベント処理です。
' OnLoad : ロード
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
    CB1.CausesValidation = True
End Sub

' コンボボックスのオーナードロー Private Sub CB1_DrawItem(ByVal sender As System.Object, _ ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles CB1.DrawItem If e.Index >= 0 Then Dim m_brush As Brush Dim m_item As DriveItem = DirectCast(CB1.Items(e.Index), DriveItem) Dim m_text As String = m_item.Name Dim m_font As Font = CB1.Font ' 表示文字列 : ドライブ名 + ボリュームラベル文字列 If m_item.Volume <> "" Then m_text &= " [" & m_item.Volume & "]" End If '背景の描画(既定の色で描画) e.DrawBackground() 'ブラシ(文字色)の設定 Select Case e.State Case DrawItemState.ComboBoxEdit m_brush = SystemBrushes.ControlText 'テキスト部 Case DrawItemState.None m_brush = SystemBrushes.ControlText 'リストの未選択時 Case Else m_brush = SystemBrushes.Window 'リストの選択時とその他 End Select '文字の描画 e.Graphics.DrawString(m_text, m_font, m_brush, e.Bounds.X + 20, e.Bounds.Y + 1) 'アイコンの描画 Dim m_image As Image m_image = IL1.Images(m_item.ImageIndex) e.Graphics.DrawImage(m_image, e.Bounds.X + 2, e.Bounds.Y) End If End Sub
' コンボボックスのドロップダウンイベント Private Sub CB1_DropDown(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles CB1.DropDown ' 初回のみドライブの更新 If m_first = False Then UpdateDrives() m_first = True End If End Sub
' コンボボックスの項目変更イベント Private Sub CB1_SelectedIndexChanged(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles CB1.SelectedIndexChanged Try Dim m_text As String = DirectCast(CB1.SelectedItem, DriveItem).Name Dim m_drive As String = m_text.Substring(0, 2) ' ドライブ名 ' ツリービューの更新 TV1.Nodes.Clear() GetNodes(m_drive) ' 最後に選択したノードと同じドライブなら復元 If m_selpath <> "" Then If StrComp(m_selpath.Substring(0, 2), m_drive, CompareMethod.Text) = 0 Then RestoreTree(m_selpath) End If End If Catch ex As Exception MessageBox.Show(ex.Message, "ERROR", _ MessageBoxButtons.OK, _ MessageBoxIcon.Stop) End Try End Sub
' ツリービューの展開前の処理イベント Private Sub TV1_BeforeExpand(ByVal sender As Object, _ ByVal e As Windows.Forms.TreeViewCancelEventArgs) Handles TV1.BeforeExpand '未展開ならサブノードを追加 Dim node As PathNode = DirectCast(e.Node, PathNode) If node.IsVested = False Then Cursor.Current = Cursors.WaitCursor GetSubNodes(node) Cursor.Current = Cursors.Default End If End Sub
' ツリービューのラベル編集イベント Private Sub TV1_AfterLabelEdit(ByVal sender As Object, _ ByVal e As Windows.Forms.NodeLabelEditEventArgs) Handles TV1.AfterLabelEdit ' 文字列に変更があれば処理開始 If e.Label <> "" Then Try Dim oldName As String = DirectCast(e.Node, PathNode).FolderPath Dim destFolder As String = IO.Path.GetDirectoryName(oldName) Dim newName As String = IO.Path.Combine(destFolder, e.Label) _ & IO.Path.GetExtension(oldName) Rename(oldName, newName) ' フォルダの名前を変更 DirectCast(e.Node, PathNode).FolderPath = newName ' ノードのプロパティを変更 Catch ex As Exception MessageBox.Show(ex.Message, "フォルダ名エラー", _ MessageBoxButtons.OK, _ MessageBoxIcon.Error) e.CancelEdit = True End Try Else e.CancelEdit = True End If End Sub
' ツリービューのマウスダウンイベント Private Sub TV1_MouseDown(ByVal sender As Object, _ ByVal e As Windows.Forms.MouseEventArgs) Handles TV1.MouseDown '選択したノードの取得 Dim node As PathNode node = DirectCast(TV1.GetNodeAt(e.X, e.Y), PathNode) 'プロパティに代入 If Not IsNothing(node) Then TV1.SelectedNode = node m_selpath = node.FolderPath RaiseEvent NodeMouseDown(m_selpath, e) End If End Sub
' ツリービューのダブルクリックイベント Private Sub TV1_DoubleClick(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles TV1.DoubleClick Dim node As PathNode = DirectCast(TV1.SelectedNode, PathNode) 'イベントを発生させる If Not node Is Nothing Then '選択したノードのパス名を返す RaiseEvent NodeDoubleClick(node.FolderPath, e) End If End Sub
| ▲TOP |

■フォルダの操作
 フォルダの操作はポップアップメニューより行いますので、フォルダ操作はメニューアイテムのクリックイベントの中への記述となります。
' ポップアップメニュー : ポップアップ時
Private Sub PUP1_Popup(ByVal sender As Object, ByVal e As EventArgs) _
                                    Handles PUP1.Popup
    Dim item As MenuItem

    If PUP1.SourceControl Is CB1 Then
        ' コンボボックスの時は「更新」の項目のみ表示 
        For Each item In PUP1.MenuItems
            item.Visible = (item Is mnUpdate)
        Next
    Else
        ' ツリービューの時はすべての項目を表示
        For Each item In PUP1.MenuItems
            item.Visible = True
        Next
        ' 使用可・不可の設定
        mnOpen.Enabled = Not IsNothing(TV1.SelectedNode)
        mnDeleteFolder.Enabled = Not IsNothing(TV1.SelectedNode)
        mnRename.Enabled = Not IsNothing(TV1.SelectedNode)
    End If
End Sub

' ポップアップメニュー : フォルダを開く Private Sub mnOpen_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles mnOpen.Click TV1_DoubleClick(Nothing, Nothing) ' ノードのダブルクリックイベント End Sub
' ポップアップメニュー : 更新 Private Sub mnUpdate_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles mnUpdate.Click UpdateWith(m_selpath) m_first = False End Sub
' ポップアップメニュー : 名前の編集 Private Sub mnRename_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles mnRename.Click If Not IsNothing(TV1.SelectedNode) Then TV1.SelectedNode.BeginEdit() End If End Sub
' ポップアップメニュー : フォルダの作成 Private Sub mnMakeFolder_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles mnMakeFolder.Click Try Dim parent, pathname As String ' パス名 Dim newNode As PathNode ' 新規ノード Dim destNodes As TreeNodeCollection ' 参照するノード群 Dim number As Integer = 0 Const defname As String = "新規フォルダ" If IsNothing(TV1.SelectedNode) Then ' 選択されたノードがないとき parent = DirectCast(CB1.SelectedItem, DriveItem).Name destNodes = TV1.Nodes Else ' 選択されたノードがあるとき parent = DirectCast(TV1.SelectedNode, PathNode).FolderPath destNodes = TV1.SelectedNode.Nodes End If ' フォルダ名の取得 : 新規フォルダ名 + ナンバー Do number += 1 pathname = IO.Path.Combine(parent, defname & number.ToString) Loop Until IO.Directory.Exists(pathname) = False IO.Directory.CreateDirectory(pathname) ' フォルダの作成 newNode = New PathNode(pathname, icoCloseFolder, icoOpenFolder) destNodes.Add(newNode) ' ノードの追加 newNode.BeginEdit() ' ラベルを編集状態にする Catch ex As Exception MessageBox.Show(ex.Message, strCaption, _ MessageBoxButtons.OK, _ MessageBoxIcon.Error) End Try End Sub
' ポップアップメニュー : フォルダの削除 Private Sub mnDeleteFolder_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles mnDeleteFolder.Click If Not IsNothing(TV1.SelectedNode) Then Dim pathname As String = DirectCast(TV1.SelectedNode, PathNode).FolderPath Dim info As New IO.DirectoryInfo(pathname) Try If CheckFileAttribute(pathname) Then Dim msg As String msg = "フォルダ [" & pathname & "] を削除します。" _ & vbCrLf _ & "フォルダ内のサブフォルダとファイルもすべて削除されます。" If MessageBox.Show(msg, strCaption, MessageBoxButtons.OKCancel, _ MessageBoxIcon.Warning) = DialogResult.OK Then info.Delete(True) ' フォルダの削除 TV1.SelectedNode.Remove() ' ノードの削除 End If End If Catch ex As Exception MessageBox.Show(ex.Message, strCaption, _ MessageBoxButtons.OK, _ MessageBoxIcon.Error) Finally If Not IsNothing(info) Then info = Nothing End Try End If End Sub
' CheckFileAttribute : ファイルの属性のチェック ' ... 引数path : チェックするパス名 ' ... 戻り値 : 処理継続OK=True / 処理中止=False Private Function CheckFileAttribute(ByVal path As String) As Boolean If (GetAttr(path) And FileAttribute.ReadOnly) = FileAttribute.ReadOnly Then ' 読み取り専用だったときの処理 Dim str As String = "フォルダ [" & path & "] は、読み取り専用です。" _ & vbCrLf _ & "削除を続けますか?" If MessageBox.Show(str, strCaption, MessageBoxButtons.YesNo, _ MessageBoxIcon.Question) = DialogResult.No Then Return False Else SetAttr(path, GetAttr(path) Xor FileAttribute.ReadOnly) ' 属性変更 End If End If Return True End Function

| ■HOME | ◆プログラムTop | ▲ページの先頭 |