エクスプローラでフォルダ名を変更する時、そのフォルダをゆっくり2回クリックするか、F2キーを押すことにより、新しいフォルダ名を入力できるようになります。ここではこれと同じことがTreeViewコントロールでできるようにする方法を紹介します。
基本的には、「ListViewのアイテムのテキストをユーザーが編集できるようにする」で紹介している方法と同じです。主な説明はそちらで行い、ここでは簡単な説明と、サンプルを示します。
ゆっくり2回クリックすることで編集できるようにするには、TreeViewコントロールのLabelEditプロパティをTrueにします。また、F2キーを押すことで編集できるようにするには、TreeViewのKeyUpイベントハンドラでF2キーが押されたかを調べ、押されていればTreeNode.BeginEditメソッドによりアイテムのラベルの編集を開始します。
ラベルの編集が始まる前にBeforeLabelEditイベントが、編集が終わった時にAfterLabelEditイベントが発生します。それぞれのイベントハンドラでNodeLabelEditEventArgs.CancelEditプロパティをTrueにすることにより、編集をキャンセルすることができます。
次の例では、ツリービューコントロール"TreeView1"のツリーノードをユーザーが編集できるようにしています。BeforeLabelEditイベントハンドラで、ルートのノードを編集できないようにしています。また、AfterLabelEditイベントハンドラで、同じ親ノード内の同じ階層に同じラベルのノードがあるかを調べ、もしあればキャンセルしています。
'フォームのLoadイベントハンドラ Private Sub Form1_Load(ByVal sender As Object, _ ByVal e As EventArgs) Handles MyBase.Load 'ツリーノードをユーザーが編集できるようにする TreeView1.LabelEdit = True 'イベントハンドラの追加 AddHandler TreeView1.BeforeLabelEdit, AddressOf TreeView1_BeforeLabelEdit AddHandler TreeView1.AfterLabelEdit, AddressOf TreeView1_AfterLabelEdit AddHandler TreeView1.KeyUp, AddressOf TreeView1_KeyUp End Sub 'BeforeLabelEditイベントハンドラ 'ツリーノードのラベルの編集が開始された時 Private Sub TreeView1_BeforeLabelEdit(ByVal sender As Object, _ ByVal e As NodeLabelEditEventArgs) 'ルートのコードは編集できないようにする If e.Node.Parent Is Nothing Then e.CancelEdit = True End If End Sub 'AfterLabelEditイベントハンドラ 'ツリーノードのラベルの編集された時 Private Sub TreeView1_AfterLabelEdit(ByVal sender As Object, _ ByVal e As NodeLabelEditEventArgs) 'ラベルが変更されたか調べる 'e.LabelがNothingならば、変更されていない If Not (e.Label Is Nothing) Then '同名のノードが同じ親ノード内にあるか調べる If Not (e.Node.Parent Is Nothing) Then For Each n As TreeNode In e.Node.Parent.Nodes '同名のノードがあるときは編集をキャンセルする If Not (n Is e.Node) AndAlso n.Text = e.Label Then MessageBox.Show("同名のノードがすでにあります。") '編集をキャンセルして元に戻す e.CancelEdit = True Return End If Next End If End If End Sub 'KeyUpイベントハンドラ 'TreeView1でキーが離れた時 Private Sub TreeView1_KeyUp(ByVal sender As Object, _ ByVal e As KeyEventArgs) Dim tv As TreeView = DirectCast(sender, TreeView) 'F2キーが離されたときは、フォーカスのあるアイテムの編集を開始 If e.KeyCode = Keys.F2 AndAlso _ Not (tv.SelectedNode Is Nothing) AndAlso _ tv.SelectedNode.IsEditing Then tv.SelectedNode.BeginEdit() End If End Sub
//フォームのLoadイベントハンドラ private void Form1_Load(object sender, EventArgs e) { //ツリーノードをユーザーが編集できるようにする TreeView1.LabelEdit = true; //イベントハンドラの追加 TreeView1.BeforeLabelEdit += new NodeLabelEditEventHandler(TreeView1_BeforeLabelEdit); TreeView1.AfterLabelEdit += new NodeLabelEditEventHandler(TreeView1_AfterLabelEdit); TreeView1.KeyUp += new KeyEventHandler(TreeView1_KeyUp); } //BeforeLabelEditイベントハンドラ //ツリーノードのラベルの編集が開始された時 private void TreeView1_BeforeLabelEdit(object sender, NodeLabelEditEventArgs e) { //ルートのコードは編集できないようにする if (e.Node.Parent == null) { e.CancelEdit = true; } } //AfterLabelEditイベントハンドラ //ツリーノードのラベルの編集された時 private void TreeView1_AfterLabelEdit(object sender, NodeLabelEditEventArgs e) { //ラベルが変更されたか調べる //e.Labelがnullならば、変更されていない if (e.Label != null) { //同名のノードが同じ親ノード内にあるか調べる if (e.Node.Parent != null) { foreach (TreeNode n in e.Node.Parent.Nodes) { //同名のノードがあるときは編集をキャンセルする if (n != e.Node && n.Text == e.Label) { MessageBox.Show("同名のノードがすでにあります。"); //編集をキャンセルして元に戻す e.CancelEdit = true; return; } } } } } //KeyUpイベントハンドラ //TreeView1でキーが離れた時 private void TreeView1_KeyUp(object sender, KeyEventArgs e) { TreeView tv = (TreeView)sender; //F2キーが離されたときは、フォーカスのあるアイテムの編集を開始 if (e.KeyCode == Keys.F2 && tv.SelectedNode != null && tv.LabelEdit) { tv.SelectedNode.BeginEdit(); } }