PROGRAMMING WORKSHOP

.Net FrameWork,VB.Net | PictureBox, LINQ to XML

System.Xml.Linq.XElement

LINQ 언어는 SQL에서도 XML에서도 다양하게 활용된다
그러니 LINQ는 한번 개념을 잡아 놓으면 ,
VB.Net상의 모든 부분에서 파워풀한 도구가 된다
XML네임스페이스에 Linq를 위한 XML을 다루는 개체가 있다
이페이지에서는 System.Xml.Linq.XElement 크래스를 사용하도록 하자
XML을 다룰때 LINQ를 같이 생각하도록 하자



우노가 facebook에 올리고,홈피앞에 나타나는 dailyEnglish는
XML로 데이타가 작성이 되어있다
xml 화일원본보기
이유는 간단하게 정보를 많이 보관하고 찾아오기 쉽고 관리하기 쉬우니까..
이 화일을 읽어서 윈도우폼의 두개의 PictureBox에 표현해 보면서
파워풀한 XElement개체를 활용해 보자

그리고 이전의 토픽에서 처리한 Thread를 응용하여 좀 쎄련된 인터페이스를 꾸며보고..
xml화일에 기록된 정보를 불러다가 어디엔가에 보관하여야 한다
하나의 정보를 불러온다면 변수하나에 넣으면 되겠지만
천여개가 되는 정보를 불러서 어딘가에 보관하여야 한다
집합체라고 하는 것이 제공된다
VBA에서의 Collection개체는 다양한 정보를 배열대신에 담아 놓는 역할을 한다
VBA의 Collection보다 훨씬 지능이 높은 집합체를 사용하게 된다

Dim Quotes As List(Of Quote)
List(Of Type)은 다양한 집합체종류중의 하나이다

List(Of Integer)
List(Of Font)
List(Of String)
List(Of Point)
...
...

등 어떤 타입의 개체이던 집합적으로 보관할수 있는 집합체이다
List(Of Quote)에서 이 소루션에서 사용하려고 만든
Quote개체는 아래와 같이 만든 사용자정의 크래스이다

Class Quote
    Public talk As String
    Public img_1 As String
    Public img_2 As String
    Public desc As String
End Class

xml화일의 정보를 인터넷에서 불러서 이 Quote개체를 만들어서
List(Of Quote)집합체에 담아 놓고 사용하게 되는 것이다
처음 윈도우폼이 나타나면 버튼을 크릭한다
버튼의 크릭이벤트 프로시져에서 아래와 같은 위의 집합체에 정보를 넣는 작업을 하게 된다

Private Sub ButtonThread1_Click(sender As System.Object, e As System.EventArgs) Handles ButtonThread1.Click
''데이타를 로딩하는 것은 시간이 걸린다
''데이타로딩할때 윈도우를 마음대로 움직일수 있어야 융통성있는 도구가 된다
''그래서 Thread개체를 하나 만들고 윈도우의 Main 스레드와 별도의 스레드에서 작업하게 한다
	Dim oNewThread As Threading.Thread
''버튼은 두가지 작업을 한다
''한번은 최초 데이타를 로딩할때와
''두번째는 데이타로딩후 집합체에 들어있는 정보를 읽고(이미지화일의 위치정보)그림화일을 가져오는 일을 한다
''이것도 역시 그림화일을 가져오려면 시간이 걸릴수도 있으니 같은 요령으로 Thread 개체를 사용하여 별개의 스레드를 운용한다
''데이타로딩은 loadDatas 프로시져를 사용하고
''이미지화일로딩은 startImages 프로시져를 사용한다
	If Me.Quotes IsNot Nothing AndAlso Me.Quotes.Count > 0 Then
		oNewThread = New Threading.Thread(AddressOf startImages)
		oNewThread.IsBackground = True
		Me.ButtonThread1.Enabled = False
	Else
		oNewThread = New Threading.Thread(AddressOf loadDatas)
		oNewThread.IsBackground = True
		Me.ButtonThread1.Enabled = False
	End If

	oNewThread.Start()
End Sub

프로그램을 띄울때 인터넷이 연결되었는지 확인할 필요가 있을 것이다
My.Computer.Network.IsAvailable 속성은
사용자의 컴퓨터에서 연결가능한 와이파이등이 있는지 확인하는 것이지
연결되었는지, 아닌지는 모른다
연결이 되었는지를 알려면
직접 네트워크상의 화일을 가져와 보는 테스트를 하는 것이 가장 좋다

Try
   Dim oClient = New System.Net.WebClient
   Dim oStream As System.IO.Stream
   oStream = oClient.OpenRead("http://uno21.com")
   Return True
Catch ex As Exception
   Return False
End Try

와 같이 접근하고자 하는 사이트를 직접 열어 보는 것이 좋다
열리지 않으면 False
열리면 True

개체를 생성후 여러번 사용하지 않는다면
아래와 같이 Using 브록을 사용하는 것도 좋다

Try
	Using oClient = New System.Net.WebClient()
		Using ostream = oClient.OpenRead("http://uno21.com")
			Return True
		End Using
	End Using
Catch ex As Exception
	Return False
End Try

VBA에서는 에러를 관리하기가 좀 깝깝했다
하지만 VB.Net에서는 일부러 에러를 내고 빠질수 있는 것이 있다

If oX.img_1 = "" OrElse oX.img_2 = "" Then Throw New Exception("")

Throw New Exception("에러내용을 임의로 메시지로 전달한다")는
에러를 일부러 내고 Try문을 빠져나가게 한다
Goto문보다는 훨씬 쎄련된 작업을 할수 있다
첨부화일에 설명하였으니 보시도록..
추가적인 설명은 다음 화일에서 계속 하도록 하고..

지난 세션의 Thread와 별도의 Thread작업에서 Main 스레드의
콘트롤에 접근하기 위하여 Invoke 메소드를 사용하는 것
그리고 Delegate를 사용하거나 Lambda Expression을 사용하는 것을
복습하는 내용이 들어있는 셈이다

***[LOG-IN]***



XML에서 가져온 정보의 다양한 분석등이 필요 없이 단순하다면
사용자정의 크래스를 만들지 말고
그냥 XElement개체를 모아놓은 집합체를 전역변수에 놓고 해도 된다
그림화일정보가 들어 있는 정도이니 그냥 XElement개체를 그냥 사용해보자
사용자개체로 집합체에 채워넣는 과정이 없으니 당연히 속도도 훨씬 빠를 것이다
그리고 해당페이지 정보를 가져오는 XML원본 노드정보를 TextBox콘트롤에 표현해 보자



정보를 가져다가 폼의 콘트롤에 뿌리는 것은 역시 별도의 Thread에서 작업을
하는 것이므로 Invoke메소드를 사용하여
Invoke메소드의 내용을 Lambda Expression을 사용한다
XML문에서 가져오는 그림정보화일이 써버의 사정상 변경되었을수도 있을 것이다
없는 정보를 불러오려고 하면 에러가 당연히 발생한다
그래서 Inovke내의 Lambda Expression내의 프로시져에 Try~Catch문을
사용하여 처리한다

Sub startImages()
Me.Invoke(Sub()
  '' XElement 개체를 모아놓은 집합체 quotes 를 직접읽어서 처리한다
  Try
	  Me.iPicIndex += 1
	  If Me.iPicIndex >= quotes_.Count Then
		  Me.iPicIndex = 0
	  End If
	  Me.ButtonThread1.Text = Me.iPicIndex + 1 & " OF " & quotes_.Count ' Me.Quotes.Count

	  Dim sImgFile As String = quotes_(Me.iPicIndex).Descendants("file").Value.Trim
	  ''그림화일의 소스가 없어졌을수도 있으므로
	  '' 에러가 나게 되므로 Try~Catch 브록을 사용하는것이 좋다/////
	  Me.PictureBox1.Load(sImgFile.Split("|")(0).Trim) ' Quotes(Me.iPicIndex).img_1)
	  Me.PictureBox2.Load(sImgFile.Split("|")(1).Trim) 'Quotes(Me.iPicIndex).img_2)
	  ''//////////////////////////////////////////////////////
	  ''XML 노드정보를 텍스트상자에..
	  Me.TextBox1.Text = quotes_(iPicIndex).ToString
  Catch ex As Exception
  Finally
	  '' Finally 브록은 중간에서 에러가 나더라도 항상 실행되는 브록이다
	  '' 에러가 나더라도 버튼은 다시 활성화하여 다음 페이지가져오는데 지장없도록 한다
	  Me.ButtonThread1.Enabled = True

  End Try

End Sub)
End Sub

***[LOG-IN]***