간단한 트리뷰(treeview) 구현
프로그램/c# asp.net tip 2010. 1. 27. 01:36 |출처 : 고수닷넷/GosuWeb/Article-detail.aspx?ArticleCode=1250
이번에는 새로 vs 2005 에서 제공하는 트리에 대해서 설명을 하고자 합니다.
다들 아시겠지만, 새로 접근하시는 분들을 위해서 강좌를 올리고자 합니다.
기존의 1.1 에는 treeview 컨트롤을 제공하지 않아서 유로 컴포넌트를 사던가 아니면
기존 vs.net 2003 에서 제공하지 않았지만, 비스무리한 treeview 를 제공한 iewebcontrol 이라는
것을 제공했습니다. 하지만 다루기가 만만치 않고, 까다롭고 많은 기능이 없어서 사용하기가
너무 어렵더군요.
따라서 서버 컨트롤인 treeview 가 vs 2005에서 제공해 주어서 편리하게 다루게 되었습니다.
우선 aspx 단에 아래와 같이 코딩을 합니다.
<asp:TreeView ID="TreeView1" runat="server" OnTreeNodePopulate="TreeView1_TreeNodePopulate" ShowLines="True"
>
<Nodes>
<asp:TreeNode Text="Customers" Value="Customers" PopulateOnDemand="True" Expanded="False"></asp:TreeNode>
</Nodes>
</asp:TreeView>
트리뷰를 aspx 디자인 페이지에 끌어다 두어서 위와 같이 편집을 하면 됩니다.
여기서 OnTreeNodePopulate 메소드는 TreeView 컨트롤의 TreeNodePopulate 이벤트를 발생시킵니다. 그러면 TreeNodePopulate 메소드가 하는 역할이 뭘까요?
"TreeView 컨트롤에서 PopulateOnDemand 속성이 true로 설정된 노드를 확장할 때 발생합니다. "
라도 설명이 되어 있더군요. PopulateOnDemand 를 true 로 설정하면 트리의 노드를 확장시킬수
있고, 이벤트 시킬수 있다는 의미랍니다.
그래서 <asp:TreeNode Text="Customers" Value="Customers" PopulateOnDemand="True" Expanded="False"></asp:TreeNode> 의 소스를 보면 PopulateOnDemand 의 속성값을 true 로
주었습니다. 따라서 비하인드에 기술된 protected void TreeView1_TreeNodePopulate(object sender, TreeNodeEventArgs e) 메소드를 노드 클릭시 이벤트가 발생된다는 의미지요.
ShowLines 메소드는 트리 보여줄때 선을 보여줄지를 의미합니다. 보여주면 뽀대가..좀 나겠죠? ㅋㅋ
그리고 처음 tree를 페이지에 뜰경우 Text="Customers" Value="Customers" 을 지정해서 최상위
트리에 Customers 라는 트리노드의 글자가 나타나도록 해둡니다. 아무것도 안뜨면 트리의 어디
부분을 클릭해서 하위노드를 펼쳐줄 수 없잖아요.. ^^
흠..그리고 Expanded 가 false 라고 되어 있죠? 이 부분은 노드가 확장 상태인지 여부를 나타내는 값을 가져오거나 설정합니다. 따라서 지금은 최상위 노드만 보여주고 하위노드는 클릭시 나타나도록
하기 위해서 false 로 했습니다.
그려면..한번 로딩해볼까요? 비하인드는 아무것도 기술하지 않고요.
그러면 이제 저...노드를 클릭하면 이벤트를 발행시켜서 하위 노드를 추가해서 뽀대나는 트리를
구현해 보죠.
노드를 선택할 경우 이벤트를 발생하는 메소드를 구현해보죠.
protected void TreeView1_TreeNodePopulate(object sender, TreeNodeEventArgs e)
{
switch (e.Node.Depth)
{
case 0:
FillCustomers(e.Node);
break;
case 1:
FillOrders(e.Node);
break;
}
}
depth 는 말그대로 깊이라는 의미인데요. 최상위 노드는 0 이고 그 밑의 자식은 1이 되겠죠?
1의 자식은 2가 되는거고요.
처음 노드를 클릭할 경우 0일 테고 FillCustomers(e.Node) 메소드를 실행하러 가겠죠?
private void FillCustomers(TreeNode parent)
{
DataSet ds = GetDataSet("select customerid,companyname from customers order by companyname");
foreach (DataRow row in ds.Tables[0].Rows)
{
TreeNode node = new TreeNode();
node.Text = row["companyname"].ToString();
node.Value = row["customerid"].ToString();
node.PopulateOnDemand = true;
node.SelectAction = TreeNodeSelectAction.SelectExpand;
parent.ChildNodes.Add(node);
}
}
GetDataSet 메소드는 실행할 경우 쿼리를 실행한 DataSet 값을 리턴해 줄것이고요. 그 DataSet
값을 받아 foreach 문을 실행해서 각각의 노드에 Text, Value , PopulateOnDemand 메소드 값 설정,
노드가 선택 모드에 있는 경우 노드가 선택될 때 발생하는 이벤트를 지정하려면 SelectAction 속성을 사용합니다. 그 속성에 TreeNodeSelectAction.SelectExpand 를 지정했는데요.
노드가 선택될 때 SelectedNodeChanged 이벤트와 TreeNodeExpanded 이벤트를 모두 발생시킬수 있답니다. 노드는 확장할 수만 있고 축소할 수는 없는 기능입니다.
이 기능뿐만 아니라 아래와 같은 기능들이 총 3가지 더 있습니다.
msdn 이 설치 되어 있다면 ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.NETDEVFX.v20.ko/cpref16/html/P_System_Web_UI_WebControls_TreeNode_SelectAction.htm을 확인해 보시기 바랍니다.
하위 노드를 추가할 경우, parent.ChildNodes.Add(node); 을 사용하고 있는것을 살펴보고 있어요.
부모.자식.Add(node특성값) 이라는 구조를 가지고 있죠. ChildNodes 메소드를 추가해서 하위노드를
추가하는 모습을 볼 수 있죠.
이제 실행을 해볼까요?
위처럼 최상위 노드의 자식인 1depth 에 위 그림 처럼 출력이 됩니다.
그러면 저 1depth 의 많은 자식들 중에도 그 아래의 하위 자식들이 각각 있겠죠?
그러면 sql 쿼리의 where 조건에 선택한 노드의 값을 넣어서 그 밑의 자식값을 추출해와서
2depth 의 하위조직을 만들 수 있겠죠.
case 1:
FillOrders(e.Node);
break;
위에서 보셨던 이벤트에서 기술한 소스 입니다. 이제 FillOrders 를 볼까요?
private void FillOrders(TreeNode parent)
{
DataSet ds = GetDataSet("select customerid,orderid from orders where customerid='" + parent.Value + "'");
foreach (DataRow row in ds.Tables[0].Rows)
{
TreeNode node = new TreeNode();
node.Text = row["orderid"].ToString();
node.Value = row["orderid"].ToString();
node.PopulateOnDemand = false;
node.SelectAction = TreeNodeSelectAction.SelectExpand;
parent.ChildNodes.Add(node);
}
}
거의 동일하죠??? 다른 점은 where 조건문을 보시면 알게 될겁니다.
선택한 노트의 값을 얻고자 한다면 parent.Value 을 사용하시면 값을 얻을 수 있습니다.
그 밑에 기술한 속성은 이미 위에서 미리 설명해서 여기서는 말씀드리지 않겠습니다.
어떠세요? 쉽게 제가 설명을 했는지 모르겠네요. 간단한 기능만 제가 설명을 해드렸는데요.
이 트리는 노드를 한번 선택했을 경우 sql 에서 값을 받아 노드를 셋팅하고, 다시 그 노드를
접거나 펼칠경우 이벤트를 다시 타서 sql 문을 실행하지 않으므로 속도면을 걱정할 필요는
없을 듯 합니다.
첨부해 드리니 테스트 해보시기 바랍니다.
감사합니다.
=======================================
사이트 : http://cafe.daum.net/aspdotnet
작성자 : 심재운
메일 : shimpark@gmail.com
=======================================