PROGRAMMING WORKSHOP

VSTO|
UserControl+ElementHost+WPF

VSTO를 한다고 하는 것은 엑셀에 .NetFrameWork의 파워를 추가하는 것이다
다른 코너에서 WPF에 대한 이야기를 많이 하였다
도대체 엑셀과 VBA를 이야기 하면서 뭔 상관도 없는(???)이야기를
자꾸 하냐고 하실 수 있을 것이다
아래의 그림은 WPF로 만든 UNO_Daily의 한 부속품을
VSTO로 만든 Custom Task Pane에 삽입하는 것을 해보기 위한것이다



아하..이렇게 모든 것이 조합이 되어 좀더 좋은 소루션을 만들수 있겠구나
회사의 어떤 메뉴얼을 전직원의 엑셀에 꽂아 주면
항상 실시간으로 내용을 써버에서 바꿔주면..
전직원의 시각적인 어떤 게시판이 될수도 있겠구나..
다양한 아이디어가 꽃을 피우게 될 것이다
그런 영감을 보여드리기 위함과 왜 WPF나 윈도우에 관한
내용을 자꾸 주절 거리는지 이해할 것이다
uno21.com이 VBA코드 조각이나 나누려고 하는 곳이 아니다
좀더 실질적인 사무자동화와 논리적임에 많은 영감을 나누고자 하는 곳이다

AddIn으로 만들어 보자
CustomTaskPane을 만들려면 항상 반드시
UserControl을 하나 만들어야 한다
소루션창에서 Add/UserControl을 하여 삽입하고
UserControl에 도구상자에서 ElementHost라는 콘트롤을 하나 삽입한후



어디있는지 찾기가 힘들 것이다
이것의 용도는 UserControl은 윈도우용컨트롤이다
그런데 여기에 족보가 다른 WPF콘트롤을 담을수 없다
윈도우와 WPF윈도우사이의 중간 아답타역할을 하는 것이 ElementHost이다
이 ElementHost가 바탕을 잡고 있어야 WPF콘트롤을 마음대로
이곳에 옮길수 있는 것이다
또한 ElementHost를 선택한 상태에서 속성창을 열고
Dock 속성을 Fill로 해주면 윈도우 UserControl전체를 ElementHost가
높이 폭등이 똑같이 채워진다

이제 ElementHost속에 WPF의 내용을 채워주기 위하여
프로젝트창에서 Add/New Item 메뉴를 크릭하여



그림과 같이 WPF UserControl을 하나 삽입한다
UserControl이 윈도우용이 있고 WPF용이 있다는 것을 이해하시고

좀더 정리하면 아래의 그림과 같이 마우스르,손으로 처리하는 부분도 있고
프로그래밍적으로 처리하는 것고 있고



WPF UserControl을 열고 작업을 하게 되면 전혀 다른
시스템이 되는 셈이다
참 흥미로운 일 아닌가?
WPF코너에서 하는 부분이 이 부분인 것이고
이것은 Silverlight와 같다고 보시면 된다(약간 다른 부분이 있지만)
더 나아가서는 이부분이 윈도우모바일폰의 프로그래밍과 연결이 된다
이렇게 설명드리는 것은 WPF가 여러분과 전혀 상관 없는 것을
한다고 생각하지 마시라는 의미가 크다

또한 중요한 것은 UserControl이라고 하는 것은
WPF용이던 Window Forms용이던 하나의 작은 윈도우폼으로
생각하시면 좋겠다
여러개의 콘트롤을 하나의 UserControl에 모아서
UserControl을 윈도우폼에 삽입하여 사용하는 것이다
마치 작은 Control(텍스트박스같은)을 모아서 윈도우를 만들듯이
마치 레고조립품을 A부속을 1,2,3 콘트롤를 모아서 만들고
B부속품을 4,2,8 콘트롤을 모아서 만들고
C라는 부속품을 4,8,7 콘트롤을 모아서 만든후
A,B,C를 모아서 완성품을 만든다던가 하는 개체 프로그래밍인 것이다
여기에서는 UserControl을 윈도우폼에 넣은 것이 아니고
CustomTaskPane이라는 윈도우기능이 아닌
.NetFrameWork에 모여있는
Microsoft.Office.Tools 라는 네임스페이스하에 있는 개체에
넣어서 사용하게 되는 것이다

또한 ElementHost는 WPF를 메인으로 하는 소루션에서
윈도우폼의 콘트롤을 사용하고 싶을때도 역시역으로
윈도우폼용 ElementHost 콘트롤을 위와 같은 요령으로 삽입후
윈도우폼만들드시 만들어 끼면 되는 것이다
어떻게 하면 만들어 놓은 개체를 다른 개체와 조합하여
사용할수 있을까를 부단히 연구하는 셈이다
이런 개념으로 VBA로 엑셀도 프로그래밍하는 생각이 좋다

uno-weekly의 리본을 보면 버튼이 많다
버튼을 크릭할때마다 CuttomTaskPane의 내용이 바뀐다
이것도 역시
UserControl을 각각의 용도에 따라서 워크시트여러장을
놓고 이럴때는 이 시트를 보고,
저럴때는 저 시트를 보는 것과 같은 요령이다
리번의 버튼을 크릭할때마다
프로젝트에 만들어 이미 만들어 놓은 해당버튼의 UserControl을
바꿔사용하는 것이다



아무튼 위에서 준비한 윈도우 UserControl속에
ElementHost넣고 이 속에 다시 WPF Usercontrol을 Addin이 로딩되면서
어떻게 프로그래밍적으로 올리는지는 정말 간단하다

Public Class ThisAddIn
'AddIn의 StartUp 이벤트프로시져
Private Sub ThisAddIn_Startup(ByVal sender As Object, _
							 ByVal e As System.EventArgs) Handles Me.Startup
        Dim oCtl As New UserControl1 ' 윈도우 콘트롤
        Dim oWPF As New UserControl2 ' WPF 콘트롤
				' CustomTaskPane 생성하면서 매개변수로 윈도우콘트롤 심고
        Dim oCTP As Microsoft.Office.Tools.CustomTaskPane = _
           Me.CustomTaskPanes.Add(oCtl, "UNO_VSTO Sample")
        ' CustomTaskPane의 위치등의 세팅
        With oCTP
            .DockPosition = _
             Office.MsoCTPDockPosition.msoCTPDockPositionRight
            .Width = 350
            .Visible = True
        End With
        ' 윈도우UserControl속에 디자인타임에 넣어준 ElementHost
        ' ElementHost의 Child속성에 WFP콘트롤을 주면 끝!!!
        oCtl.ElementHost1.Child = oWPF

    End Sub

    Private Sub ThisAddIn_Shutdown(ByVal sender As Object, _
           ByVal e As System.EventArgs) Handles Me.Shutdown

    End Sub

End Class

이것은 이렇게 그냥 위와 같은 공식대로 넣으면 된다
문제는 내용이 되는 WPF콘트롤의 내용을 만드는 것이다..
여기에 여러분의 업무에 대한 창의력이나
기발난 생각들을 프로그래밍하는 것이 실제의 일이 될 것이다

WPF콘트롤에 대한 내용은
아래 화일의 코드모듈에서 주석으로 설명을 달았읍니다

***[LOG-IN]***