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