이번에는 계층적으로 자료를 표시할 수 있는 TreeView 사용법을 알아봅시다.
이번 실습에서는 트리 뷰의 부모의 첫번째 자식, 마지막 자식으로 노드를 추가하는 방법과 선택한 노드의 이전, 이후로 추가하는 방법, 노드를 삭제하는 방법 및 트리의 항목을 펼치거나 축소하는 방법 등을 알아볼게요.
다음은 Form1의 자식 컨트롤 Name 및 형식입니다.
No | Name | 컨트롤 형식 | 설명 |
1 | tv_demo | TreeView | 데모 트리 뷰 |
2 | tbox_parent | TextBox | 부모 노드 텍스트 박스 |
3 | tbox_child | TextBox | 자식 노드 텍스트 박스 |
4 | btn_add_first | Button | 부모의 첫번째 자식으로 추가 버튼 |
5 | btn_add_last | Button | 부모의 마지막 자식으로 추가 버튼 |
6 | lbox_brothers | ListBox | 선택한 노드의 자식 노드 목록 |
7 | btn_add_prev | Button | 선택한 자식의 이전 노드로 추가 버튼 |
8 | btn_add_next | Button | 선택한 자식의 다음 노드로 추가 버튼 |
9 | btn_expand | Button | 트리 뷰 펼치기 |
10 | btn_collapse | Button | 트리 뷰 축소하기 |
11 | btn_remove | Button | 선택 노드 제거하기 |
트리 뷰의 AfterSelect 이벤트 핸들러를 등록합니다.
private void tv_demo_AfterSelect(object sender, TreeViewEventArgs e) {
선택 항목의 자식들을 표시할 lbox_brothers의 아이템 항목을 지워줍니다.
lbox_brothers.Items.Clear();
트리 뷰에는 선택한 노드를 SelectedNode 속성으로 가져오기 할 수 있습니다.
TreeNode node = tv_demo.SelectedNode; if (node == null) {
선택한 노드가 없을 때 tbox_parent의 Text 속성을 비워줍니다.
tbox_parent.Text = string.Empty;
그리고 tbox_paretn의 Tag에는 트리 뷰의 TopNode로 설정합시다.
tbox_parent.Tag = tv_demo.TopNode;
선택한 노드가 없으므로 삭제 버튼은 비활성화 합니다.
btn_remove.Enabled = false; return; }
선택한 노드가 있다면 tbox_parent의 Text 속성과 Tag 속성을 선택한 노드로 설정합니다.
tbox_parent.Text = node.Text; tbox_parent.Tag = node;
선택한 노드가 있기 때문에 삭제 버튼을 활성화합니다.
btn_remove.Enabled = true;
그리고 선택한 노드의 Nodes 컬렉션에 있는 자식 노드들을 lbox_brothers 항목에 추가합니다. 여기서 lbox_brothers라고 명명한 이유는 추가할 노드의 형제들이라는 의미입니다. 물론 선택한 노드의 자식들이죠.
foreach (TreeNode snode in node.Nodes) { lbox_brothers.Items.Add(snode); } }
첫번째 자식으로 추가 버튼의 클릭 이벤트 핸들러를 등록합니다.
private void btn_add_first_Click(object sender, EventArgs e) {
tbox_parent.Tag에 설정해 두었던 TreeNode를 참조합니다.
TreeNode node = tbox_parent.Tag as TreeNode;
만약 node가 null이면 트리 뷰의 Nodes 컬렉션에 추가합니다. 원하는 위치에 추가할 때는 Insert 메서드를 사용합니다.
if (node == null) { tv_demo.Nodes.Insert(0, tbox_child.Text); }
node가 null이 아니면 node의 Nodes 컬렉션에 추가하고 노드를 펼칩니다.
else { node.Nodes.Insert(0,tbox_child.Text); node.Expand(); }
tbox_childe의 Text 속성을 빈 문자열로 설정합니다.
tbox_child.Text = string.Empty; }
마지막 자식으로 추가 버튼의 클릭 이벤트 핸들러를 등록합시다.
private void btn_add_last_Click(object sender, EventArgs e) {
tbox_parent의 Tag 속성에 설정한 TreeNode를 참조합니다.
TreeNode node = tbox_parent.Tag as TreeNode;
마지막 자식으로 추가할 때는 Add 메서드를 호출합니다.
if (node == null) { tv_demo.Nodes.Add(tbox_child.Text); } else { node.Nodes.Add(tbox_child.Text); node.Expand(); } tbox_child.Text = string.Empty; }
lbox_brothers 리스트 박스의 선택 항목 변경 이벤트 핸들러를 등록합시다.
private void lbox_brothers_SelectedIndexChanged(object sender, EventArgs e) {
선택 항목이 있는지 여부에 따라 이전 자식으로 추가 버튼과 다음 자식으로 추가 버튼의 활성화 및 비활성화 여부를 설정합니다.
bool selected = (lbox_brothers.SelectedIndex != -1); btn_add_prev.Enabled = selected; btn_add_next.Enabled = selected; }
이전 자식으로 추가 버튼의 클릭 이벤트 핸들러를 등록합시다.
private void btn_add_prev_Click(object sender, EventArgs e) {
lbox_brothers의 선택 항목을 TreeNode 형식으로 참조합니다.
TreeNode tn = lbox_brothers.SelectedItem as TreeNode;
트리 노드에는 Parent 속성으로 부모 노드를 가져오기할 수 있습니다.
TreeNode pn = tn.Parent;
부노 모드의 Nodes 컬렉션에 선택한 형재 노드의 Index에 추가합니다.
pn.Nodes.Insert(tn.Index, tbox_child.Text); tbox_child.Text = string.Empty; }
다음 자식으로 추가 버튼의 클릭 이벤트 핸들러를 등록합시다.
private void btn_add_next_Click(object sender, EventArgs e) {
다음 자식으로 추가하기 위해 선택한 형재 노드의 Index+1 위치에 추가합니다.
TreeNode tn = lbox_brothers.SelectedItem as TreeNode; TreeNode pn = tn.Parent; pn.Nodes.Insert(tn.Index+1, tbox_child.Text); tbox_child.Text = string.Empty; }
펼기기와 축소하기 버튼의 클릭 이벤트 핸들러를 등록합시다. 펼치기와 축소하기를 위해 트리 뷰에서는 ExpandAll 메서드와 CollapseAll 메서드를 제공합니다.
private void btn_expand_Click(object sender, EventArgs e) { tv_demo.ExpandAll(); } private void btn_collapse_Click(object sender, EventArgs e) { tv_demo.CollapseAll(); }
삭제 버튼의 클릭 이벤트 핸들러를 등록합시다.
private void btn_remove_Click(object sender, EventArgs e) {
노드를 제거할 때는 노드 자신의 Remove 메서드를 사용합니다. 여기서는 선택한 노드를 제거할 것이므로 SelectedNode 속성에 있는 노드 개체를 Remove 합니다.
tv_demo.SelectedNode.Remove();
선택한 노드를 제거했으니 tbox_parent의 Tag 속성과 Text 속성을 지워줍니다.
tbox_parent.Tag = null; tbox_parent.Text = string.Empty; }
▷Form1.cs
using System; using System.Windows.Forms; namespace Ex_TreeView { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void tv_demo_AfterSelect(object sender, TreeViewEventArgs e) { lbox_brothers.Items.Clear(); TreeNode node = tv_demo.SelectedNode; if (node == null) { tbox_parent.Text = string.Empty; tbox_parent.Tag = tv_demo.TopNode; btn_remove.Enabled = false; return; } tbox_parent.Text = node.Text; tbox_parent.Tag = node; btn_remove.Enabled = true; foreach (TreeNode snode in node.Nodes) { lbox_brothers.Items.Add(snode); } } private void btn_add_first_Click(object sender, EventArgs e) { TreeNode node = tbox_parent.Tag as TreeNode; if (node == null) { tv_demo.Nodes.Insert(0, tbox_child.Text); } else { node.Nodes.Insert(0,tbox_child.Text); node.Expand(); } tbox_child.Text = string.Empty; } private void btn_add_last_Click(object sender, EventArgs e) { TreeNode node = tbox_parent.Tag as TreeNode; if (node == null) { tv_demo.Nodes.Add(tbox_child.Text); } else { node.Nodes.Add(tbox_child.Text); node.Expand(); } tbox_child.Text = string.Empty; } void lbox_brothers_SelectedIndexChanged(object sender, EventArgs e) { bool selected = (lbox_brothers.SelectedIndex != -1); btn_add_prev.Enabled = selected; btn_add_next.Enabled = selected; } private void btn_add_prev_Click(object sender, EventArgs e) { TreeNode tn = lbox_brothers.SelectedItem as TreeNode; TreeNode pn = tn.Parent; pn.Nodes.Insert(tn.Index, tbox_child.Text); tbox_child.Text = string.Empty; } private void btn_add_next_Click(object sender, EventArgs e) { TreeNode tn = lbox_brothers.SelectedItem as TreeNode; TreeNode pn = tn.Parent; pn.Nodes.Insert(tn.Index+1, tbox_child.Text); tbox_child.Text = string.Empty; } private void btn_expand_Click(object sender, EventArgs e) { tv_demo.ExpandAll(); } private void btn_collapse_Click(object sender, EventArgs e) { tv_demo.CollapseAll(); } private void btn_remove_Click(object sender, EventArgs e) { tv_demo.SelectedNode.Remove(); tbox_parent.Tag = null; tbox_parent.Text = string.Empty; } } }