PROGRAMMING WORKSHOP

.Net FrameWork,VB.Net |TreeView

TreeView

정보를 계층별로 보기(Hierarchy view)

앞에서 DataTable,DataGridview등을 사용하면서 VB.Net언어를 익숙하게 하였었다
이제 다른 시각에서 정보를 보는 TreeView콘트롤을 사용해 보면서
관련하여 DataTable,DataGridView,LINQ등, VB.Net과 .NetFrameWork의
다양함을 경험 해보도록 하자

우선 간단하게 하나 만들어 보자


''이벤트를 사용할수 있게 WithEvents 로 전역변수로 TreeView개체변수를 하나 만들고..
WithEvents oTV As TreeView
''폼로딩하면서..
Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
''TreeView 만드는 프로시져 하나 만들고
	setTreeView()     
	Me.AutoSize = True
	Me.Font = New Font("맑은 고딕", 9)
End Sub
'' 폼로딩이벤트에서 호출한 TreeView만들기 쌤플
Sub setTreeView()
'' 전역변수의 oTV변수에 TreeView개체 생성하고
	oTV = New TreeView

	Dim iX As Integer
	Dim iY As Integer
	Dim iZ As Integer
''TreeView콘트롤을 구성하는 개체는 TreeNode로 간단하게 만들수 있다
''변수 두개 준비하고..
	Dim oParent As TreeNode
	Dim oChild As TreeNode

''중첩된 순환을 3번한다
''즉 3단계 레벨이 된다
''첫번째 순환..순환의 갯수는 랜덤갯수만큼..
	For iX = 1 To Int(Rnd() * 10) + 5
''첫째 순환에서 최상위 TreeNode를 만들고
''Text값주고..
''이렇게 만든 TreeNode는 TreeView의 첫째레벨 Node가 된다
		oParent = New TreeNode
		oParent.Text = Chr(64 + iX)
''첫번째 순환문에서는 TreeView의 Nodes집합체에 Add시키고
		oTV.Nodes.Add(oParent)
		For iY = 1 To Int(Rnd() * 10) + 2
''두번째 순환문에서 만드는 TreeNode는 TreeView의 Nodes집합체에 붙이지 않고
''첫째순환에서 만든 TreeNode의 Nodes집합체에 추가시키다		
			oChild = New TreeNode(oParent.Text & "-" & Chr(64 + iY))
			oParent.Nodes.Add(oChild)
			For iZ = 1 To Int(Rnd() * 10) + 2
''세번째 레벨...이것은 두번째 레벨의 TreeNode의 Nodes집합체에 추가시키고..			
				oChild.Nodes.Add(New TreeNode(oChild.Text & "-" & Int(Rnd() * 1000) + 1000))
			Next
		Next
	Next
''TreeView의 폭과 높이
''그리고 TreeView콘트롤을 폼의 Controls집합체에 추가시켜야 하고	
	oTV.Width = 400
	oTV.Height = 300
	Me.Controls.Add(oTV)

End Sub

'' WithEvents로 선언한 TreeView의 이벤트프로시져에
'' 아래와 같이 작성하여 폼의 Text속성에 선택된 TreeNode개체의 
'' FullPath 속성을 읽어서 표현해보고..
Private Sub oTV_AfterSelect(sender As Object, e As System.Windows.Forms.TreeViewEventArgs) Handles oTV.AfterSelect
	Try

	'' FullPath 속성은 해당 TreeNode의 상위 개체부터 순서대로 \ 문자로 구분되어 있다
		Me.Text = oTV.SelectedNode.FullPath.Replace("\", " -> ")
	Catch ex As Exception

	End Try
End Sub

위의 코드를 실행하면 아래와 같이 간단하게 만들어진다



상위레벨의 TreeNode의 자식 TreeNode로 구성이 되는 계층형으로 데이타를 볼수 있는 것이다
테이블의 내용을 계층별로 볼수 있는 좋은 도구 인것이다

TreeView+DataTable+DataGridView+LINQ

이번에는
테이블형식과 TreeView를 같이 구현해 보자



Flat테이블 형식과 TreeVeiw로 보는 형식으로 보는 방식이 뭐가 다른지 볼수 있다
데이타를 다루면서 Hierarchy(계층별, 그룹핑)으로 보는 시각을 갖어야 한다

Sub setTreeViewAndDataGridView()
	''TreeView콘트롤 만들고
	oTV = New TreeView
	'' DataGridView 콘트롤 만들고
	oDGV = New DataGridView
	''테이블개체 만들고
	oTable = New DataTable

	Dim oParent As TreeNode
	Dim oChild As TreeNode
	Dim oGChild As TreeNode

	'' 테이블의 열구조만들고 /////////////////////////////////
	For iX As Integer = 1 To 3
		oTable.Columns.Add("Data_" & iX, GetType(String))
	Next
	''//////////////////////////////////////////////////

	For iX As Integer = 1 To Int(Rnd() * 10) + 5
		oParent = New TreeNode
		oParent.Text = Chr(64 + iX)
		oTV.Nodes.Add(oParent)
		For iY As Integer = 1 To Int(Rnd() * 10) + 2
			oChild = New TreeNode(oParent.Text & "-" & Chr(64 + iY))
			oParent.Nodes.Add(oChild)
			For iZ As Integer = 1 To Int(Rnd() * 10) + 2

				oGChild = New TreeNode(oChild.Text & "-" & Int(Rnd() * 1000) + 1000)
				oChild.Nodes.Add(oGChild)
				''위의 내용은 위의 TreeView와 같고 아래에
				''테이블의 열을 하나식 추가해 나가자..
				''TreeNode의 각각의 값을 테이블의 몇번째열에 넣는지..
				Dim oRow As DataRow = oTable.NewRow
				oRow.Item(0) = oParent.Text
				oRow.Item(1) = oChild.Text
				oRow.Item(2) = oGChild.Text
				''하나의 행을 만들고 각 셀에 값을 넣고 테이블의 행에 추가..
				oTable.Rows.Add(oRow)
			Next
		Next

	Next
	'' DataGridView의 DataSource를 테이블개체로 하고
	'' 나머지는 각콘트롤의 위치 잡는 것은 별문제 아니고..
	oDGV.DataSource = oTable
	oDGV.Width = 400
	oDGV.Height = 300
	oTV.Left = oDGV.Width + 6
	oTV.Width = 300
	oTV.Height = 300
	Me.Controls.Add(oDGV)
	Me.Controls.Add(oTV)
End Sub

테이블형식은 중복되는 정보가 줄줄이 채워져 있는 셈이고..
TreeView는 각계층별로 중복되는 것은 배제하고 유일한 값만 표현하게 된다

TreeView의 TreeNode개체를 선택하면
같은 정보를 갖고 있는 DataGridView의 해당정보의 위치로 행이 스크롤하게 하고 싶고
선택된 셀에 색상을 칠하여 시각적으로 보기 편하게 하고 싶은 것이
프로그래밍하는 사람의 욕구이다
DataGridView의 행을 프로그래밍적으로 스크롤하려면 어떤 속성?
DataGridView의 현재선택된 셀에 색상을 칠하려면 어떤 속성?
이런 속성이나 메소드만 찾으면 된다



위의 것을 구현하기 위하여 하나는 전통적인 순환방법이고
다른 하나는 최신 기술인 LINQ를 사용하는 방법이다
두개를 비교하면서 학습하시는 것이 좋을 것이다
새 기술이 좋은 것이니까..

Sub formatDGVBySelectNode(oNode As TreeNode)


	Try
		'' DataGridView의 모든 셀의 서식초기화
		For Each oRow As DataGridViewRow In oDGV.Rows
			For Each oCell As DataGridViewCell In oRow.Cells
				oCell.Style.BackColor = Color.White
			Next
		Next


		''TreeNode의 Level속성은 현재 몇번째 계층에 있는지 알수 있다
		''물론 최상위 TreeNode의 레벨은 0이다


		''////////////////////////전통적인 순환방법///////////////////////////
		Dim iLevel As Integer = oNode.Level
		Dim iScroll As Integer
		'' DataGridView의 행을 순환한다
		For Each oRow As DataGridViewRow In oDGV.Rows
			'' DataGridViewRow의 각각의 Cell을 순환한다
			For Each oCell As DataGridViewCell In oRow.Cells
				'' 선택받지 못한 셀은 바탕색을 흰색으로 하고
				oCell.Style.BackColor = Color.White
				'' 선택된 셀의 첫째행에 해당 하는 부분을 변수에 표시하고
				If oRow.Cells(iLevel).Value = oNode.Text Then
					If iScroll = 0 Then
						iScroll = oRow.Index
					End If
					oRow.Cells(iLevel).Style.BackColor = Color.Yellow
				End If
			Next
		Next
		''서식이 끝난후 해당셀들의 첫째셀의 행으로 스크롤한다
		oDGV.FirstDisplayedScrollingRowIndex = iScroll
		''///////////////////////////////////////////////////////////////////////


		''//////////////////////////////LINQ 로 처리하기..//////////////////////////

		'' LINQ 로 해당되는 Cell들만 수집해서 처리하는 방법
		'' 좀더 쎄련되고, 최근의 기술을 실천하는 것...

		'' DataGridView의 각 행을 순환하면서
		'' 또 각행의 셀을 순환하면서
		'' 조건이 각셀의 값이 선택된 TreeNode의 Text값과 같으면
		'' 해당 셀을 선택(Select)한다...
		'' 하나는 셀자체, 그리고 다른 하나는 셀의 행번호, 두개의 값을 받는 것
		'' 이것을 개체변수 oListCells에 담는다
		'' 물론 순환이 이루어지지만 LINQ엔진내부에서 일어나는 것이고
		'' 순환의 방식도 최신기술에 따른 메모리관리에 최적화된 것...

		'Dim oListCells = From oRow As DataGridViewRow In oDGV.Rows,
		'            oCell As DataGridViewCell In oRow.Cells
		'            Where oCell.Value = oNode.Text
		'            Select oCell, oCell.RowIndex

		'For Each oCell In oListCells
		'    oCell.oCell.Style.BackColor = Color.Yellow
		'Next

		'oDGV.FirstDisplayedScrollingRowIndex = oListCells(0).RowIndex
	Catch ex As Exception
	End Try
End Sub



***[LOG-IN]***