TreeViewコントロールの操作


ノードが選択されたときに処理する

ツリー状に表示したノードは、一般的に選択されることで何かの処理を行います。ノードが選択されたときのイベントと、クリックされたノードを取得する方法を解説します。

ノードが選択されるとNodeClickイベントが発生します。次のコードは、クリックされたノードを表示します。

Private Sub TreeView1_NodeClick(ByVal Node As MSComctlLib.Node)
    MsgBox Node
End Sub

上図は「田中」をクリックしたところです。

NodeClickイベントでは、クリックされたノードがNodeに格納されます。このとき、格納されるのは表示されている文字列ではなく、Nodeオブジェクトそのものです。上記サンプルコードの「MsgBox Node」はプロパティを省略しているので、標準のプロパティであるTextプロパティが参照されたわけです。正確には「MsgBox Node.Text」と同じことですね。

矢印キーなどを使ってノードの選択を移動したときもNodeClickイベントが発生します。ただし、[+]ボタンや[-]ボタンをクリックして子ノードの展開を切り替えただけでは発生しません。

よく使われるプロパティ

TreeViewコントロールでよく使われるプロパティを紹介します。

・Countプロパティ

Nodeオブジェクトではなく、Nodesコレクションのプロパティです。登録されているノードの数を返します。

Private Sub CommandButton2_Click()
    MsgBox TreeView1.Nodes.Count
End Sub

・Indexプロパティ

そのノードが何番目かを表します。

任意のノードを特定するには、Index番号で指定するやり方と、ノードの名前で指定するやり方があります。ただし、ノードの名前とは表示されている文字列ではなく、引数Keyで指定した重複しないノード名のことです。「田中」を登録するとき引数Keyに「tanaka」を指定したのでしたら、Nodes("tanaka")と指定しなければなりません。

また、Index番号は表示されている順番ではなく、登録した順番に付けられます。解説で使用しているサンプルは、「氏名」→「住所」→「田中」の順で登録していますので、Index番号もその順番になります。

Private Sub CommandButton2_Click()
    Dim i As Long, buf As String
    For i = 1 To TreeView1.Nodes.Count
        buf = buf & TreeView1.Nodes(i) & vbCrLf
    Next i
    MsgBox buf
End Sub

・Parentプロパティ

そのノードが子の場合、親ノードを返します。

Nodes("tanaka").ParentはNodes("_Name")となります。ただし「氏名」や「住所」など親ノードが存在しないノードのParentプロパティはNothingが返ります。したがって「MsgBox Node.Parent」のようにして、クリックされたノードの親ノードを取得しようとするコードは、「氏名」や「住所」のような最上位ノードでエラーになります。NothingをMsgBoxで表示することができないからです。ParentプロパティがNothingかどうかは、Is演算子で判定します。

次のコードは、クリックされたノードに親がいたら表示します。

Private Sub TreeView1_NodeClick(ByVal Node As MSComctlLib.Node)
    If Node.Parent Is Nothing Then
        MsgBox "親はいません"
    Else
        MsgBox Node.Parent
    End If
End Sub

・Childrenプロパティ、Childプロパティ

Childrenプロパティは、そのノードにいくつの子がいるかを返します。

Childプロパティは、そのノードの第一子(最初の子)を返します。

Childrenプロパティの対象になるのは直下の子だけです。孫の数は含まれません。「田中」のChildrenプロパティは「2」で、「氏名」のChildrenプロパティは「1」になります。

Childプロパティは、先頭の子ノードだけを返します。すべての子ノードを返すのではありませんので注意してください。また、子がいないノードのChildプロパティは、やはりNothingを返します。ただし、子がいないノードでもChildrenプロパティは「0」を返します。ChildプロパティがNothingかどうかを判定するより、Childrenプロパティが0かどうかを調べる方が良いでしょう。

次のコードは、クリックされたノードに子がいたら表示します。

Private Sub TreeView1_NodeClick(ByVal Node As MSComctlLib.Node)
    If Node.Children > 0 Then
        MsgBox Node.Child
    Else
        MsgBox "子はいません"
    End If
End Sub

・FullPathプロパティ、Rootプロパティ

FullPathプロパティは、そのノードまでのフルパスを返します。

Rootプロパティは、そのノードの最上位ノードを返します。

「趣味」のFullPathプロパティは「氏名\田中\趣味」を返します。また「趣味」のRootプロパティは「氏名」を返します。

次のコードは、クリックされたノードのフルパスとルートを表示します。

Private Sub TreeView1_NodeClick(ByVal Node As MSComctlLib.Node)
    MsgBox "フルパス:" & Node.FullPath & vbCrLf & _
           "ルート:" & Node.Root
End Sub

子ノードを展開する

Addメソッドで子ノードを登録しても、子ノードは展開されない状態で登録されます。子ノードの展開を設定するのは、NodeオブジェクトのExpandedプロパティです。ExpandedプロパティにTrueを設定すると開き、Falseを設定すると閉じます。

次のコードは、各ノードを登録した後で「氏名」の子ノードを展開します。

Private Sub CommandButton1_Click()
    With TreeView1.Nodes
        .Add Key:="_Name", Text:="氏名", Image:="book"
        .Add Key:="_Address", Text:="住所", Image:="book"
        .Add Relative:="_Name", Relationship:=tvwChild, Key:="tanaka", Text:="田中", Image:="sheet"
        .Add Relative:="tanaka", Relationship:=tvwChild, Text:="趣味"
        .Add Relative:="tanaka", Relationship:=tvwChild, Text:="特技"
    End With
    TreeView1.Nodes("_Name").Expanded = True
End Sub

ノードを削除する

ノードを削除するには、NodesコレクションのRemoveステートメントを実行します。Removeステートメントは、引数に削除したいノードのIndex番号を指定します。引数にNodeオブジェクトを指定するとエラーになりますので注意してください。ここでは、現在選択されているノードの取得も解説します。

次のコードは、現在選択されているノードを削除します。

Private Sub CommandButton2_Click()
    With TreeView1
        If MsgBox(.SelectedItem & vbCrLf & "を削除しますか?", 36) = vbYes Then
            .Nodes.Remove .SelectedItem.Index
        End If
    End With
End Sub

現在選択されているノードは、TreeViewコントロールのSelectedItemプロパティで取得できます。SelectedItemプロパティは選択されているNodeオブジェクトを返します。Removeステートメントは引数にIndex番号を指定しなければいけませんから、SelectedItem.Indexとしています。

なお、すべてのノードを削除するときは「TreeView1.Nodes.Clear」とClearステートメントを実行します。