PROGRAMMING WORKSHOP

.NetFrameWork | WPF 프로그램 시작하기

새로운 기술은 항상 사람을 흥분하게 만든다
WPF는 차세대 버전 윈도우라고 보면 쉬울 것이다
기존의 윈도우는 실은 엑셀 VBA에서 UserForm의 좀더 강력하게 확장된
버전으로 보면 되는 것이라서 별로 신나는 것이 없다
그러나 WPF..차세대 윈도우는 완벽히 .NetFramwWork를 기반으로 하는
.NetFrameWork를 웹과 WPF같은 차세대표현도구를 의식하고 만들었다고
하는 것이 맞는 말일 것이다
그런데 이것을 강좌에 포함할까..말까..무척이나 망설이던 것이지만..
실은 우노가 즐겨 사용하는 것이 WPF인데 고전적 윈도우를 계속 이야기하는 것도
앞뒤가 안맞는다..
그래서 WPF코너를 시작하기로 한다
WPF는 그냥 Silverlight로 확장이 되는 것이니..
WPF를 하면 Silverlight는 자동으로 얻는 것이고
더불어 윈도우 폰등과 같은 것의 개발의 기초가 되는 것들이다

그런데 이것으로 무엇을 만들지???
UNO_Daily프로그램이 이것으로 구현된 것이고..
무척 쉽게 개발되는 것이다
이것을 습득하기 좋은 기초는 HTML언어에 능숙하였다면
더더욱 좋았을 것이다
웹이 발전하고..그러면서 윈도우를 웹과 같이 표현하는 방법이 없을까..
라는 컨셉에서 발전되어 가고 있는 것이다

특히나 WPF, Silverlight는 에니메이션등을 코딩없이도
흥미롭게 할 수 있는 것이다
물론 코딩을 추가하면 좀더 파워풀해지고..

Window 폼에서의 모든 개체는
System.Windows.Forms
이하의 개체들로 구성이 되지만
WPF는
System.Windows.Controls
System.Windows.Media
이하의 개체들이 구성 요소들이 된다
Window폼이나 WPF 폼이나 모두 .NetFrameWork를 기반으로 진행되는 것이니..
Window폼에서 전혀 쌩뚱맞은 것으로 빠져나온 이야기가 아니니까..
별로 거부감을 갖을 필요는 없다

우선 WPF는 Animation(에니메이션)이 특징적인 것이니..
에니메이션이 흥미롭고 새로운 도구를 습득할때 좋은 방법이다



위와 같이 새프로젝트를 만들면(2008버전이던 2020이던 마찬가지)
아래와 같이 기존의 윈도우개발환경과는 전혀 낯선 환경이 나타난다
하지만 친해지면 참으로 편리하고 새로운 맛이 난다



역시 기존의 윈도우폼과 마찬가지로 VB모듈시트창이 있고
윈도우 시각적디자인 창이 있다
VB모듈창은 같지만 시각적 디자인 창은 두개로 나누어서
하나는 콘트롤을 끌어다 놓고 시각적으로 배치를 마우스로 처리하는
윈도우가 있고..또 하나는 XAML이라는 편집창이 있다
WPF 프로그램은 바로 이 XAML이 기본핵심이다

윈도우창에 버튼을 하나 끌어다 놓으면 자동으로 XAML문이
자동으로 작성되는 것을 볼수 있을 것이다
반대로 XAML편집기에 직접 코딩을 하면 또한 콘트롤이 창에
자동으로 생성되는 것을 볼수 있다

참 매력적인 개발도구이다

<Window x:Class="Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300"> <Grid> </Grid> </Window>

위의 내용을 보면
제목이 Window1 이고
높이가 300 이고
폭이 300 이라는 윈도우폼이 하나 만들어지라는 XAML문이다
높이나, 폭을 위의 XAML문에서 자판으로 수정하는 것이 속성창을
찾고 어쩌고 하는 것 보다 빠를것이다

그리고 Grid라는 콘트롤이 기보적으로 하나 만들어진것이다

위의 내용을 아래와 같이 편집을 하여 보면..

<Window x:Class="Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="230" Width="300"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="auto" /> <ColumnDefinition Width="auto" /> <ColumnDefinition Width="auto" /> </Grid.ColumnDefinitions> <Button Content="Button" Height="23" Name="Button1" Width="75" Grid.Column="1" /> <Button Content="Button" Height="23" Name="Button2" Width="75" Grid.Column="0" /> <Button Content="Button" Height="23" Name="Button3" Width="75" Grid.Column="2" /> </Grid> </Window>

열이 3개짜리 테이블이 만들어지고
각각의 열에 버튼이 하나씩 만들어지게 된다
콘트롤을 도구상자에서 끌어다 놓고..속성창에서 속성을 바꾸고
하는 것 보다 훨씬 지능적이고 빠르고,정확하게.. 프로그래밍스럽다



XML문과 같은 형식인 것이다
XML문은 정보만을 담아두는 그릇이지만
XAML문은 서식을 표현하는 것이다
웹페이지의 HTML문은 정보와 서식을 같이 짬뽕으로 처리하지만
XAML문은 아주 지능이 높은 서식처리(모양을 내는)를 하는 언어인셈이다
모든 서식과 모양내기를 문자열로 표현하는 것이고
XAML의 엔진이 이것을 시각적, 그래픽으로 번역하여 윈도우창에 나타나게
하는 것이다

물론 이 내용을 VB로 개체생성하고 붙이고..또만들고 하여도 된다
하지만 XAML은 VB에서 할일의 부담을 아주 많이 덜어준다고 보면 된다
만약 VB에서 에니메이션을 한다고 하면
VB로 프로그래밍적으로 처리하여야 한다
그러나 WPF에서는 XAML의 문자열정보를 뚝딱..뚝딱 편집하여도
에니메이션이 되는 것이다

아래의 내용을 그냥 복사하여 XAML편집기의 내용과 몽땅 바꾸고
실행을 해보시고, 각 버튼을 전부크릭하여 보시면
어떤 에니메이션을 하는지 볼수 있을 것이다

<Window x:Class="Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="230" Width="300"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="auto" /> <ColumnDefinition Width="auto" /> <ColumnDefinition Width="auto" /> </Grid.ColumnDefinitions> <Button Content="Button" Height="23" Name="Button1" Width="75" Grid.Column="0"> <Button.Triggers> <EventTrigger RoutedEvent="Button.Click"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetProperty="Height" To="100" Duration="0:0:05" AutoReverse="True" /> </Storyboard> </BeginStoryboard> </EventTrigger> </Button.Triggers> </Button> <Button Content="Button" Height="23" Name="Button2" Width="75" Grid.Column="1"> <Button.Triggers> <EventTrigger RoutedEvent="Button.Click"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetProperty="Width" From="30" To="200" Duration="0:0:03" AutoReverse="True" /> </Storyboard> </BeginStoryboard> </EventTrigger> </Button.Triggers> </Button> <Button Content="Button" Height="23" Name="Button3" Width="75" Grid.Column="2"> <Button.RenderTransform> <RotateTransform x:Name="moveMe" Angle="0" /> </Button.RenderTransform> <Button.Triggers> <EventTrigger RoutedEvent="Button.Click"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="moveMe" Storyboard.TargetProperty="Angle" From="0" To="360" Duration="0:0:05" AutoReverse="True" RepeatBehavior="Forever" /> </Storyboard> </BeginStoryboard> </EventTrigger> </Button.Triggers> </Button> </Grid> </Window>

WPF의 파워와 매력을 볼 수 있었을 것이다
VB코딩 하나도 없이 XAML문으로 재미있는 동작이 되는 것을
볼수 있었다

위의 내용을 척 보기에는 무지하게 복잡해 보이지만
죄다 같은 소리다..

WPF는 <Window>...</Window> 태그내에서 모두 만들어진다
Button은 <Button></Button> 태그로 만들어지고
모든 개체가 여는 태그와 닫는 태그로 만들어진다
열었으면 반드시 닫아야하고, 대문자 소문자 반드시 구별하여야 하고
모든 것이 개체다
에니메이션을 하는 것도 역시 마찬가지다
에니메이션을 하는 것을 총괄하는 본부사령개체는 StoryBoard라는 개체이다
하나의 StoryBoard개체가 여러개의 에니메이션을 갖고 있을수 있다
예를 들어서 폭이 넓어지거나 좁아지면서 바탕색이 빨강색에서
파랑색으로 변할수도 있는 것이다..동시 여러개의 에니메이션이 이루어질수
있는 것이고 이런 것을 관리하는 것이 StoryBoard개체이다
그래서
<StoryBoard>......</StroyBoard> 라는 태그로 둘러쌓고 그 내부에
에니메니션이 들어가는 것이다

또 에니메이션개체만 있어서는 안된다..
에니메이션을 일으키는 무언가가 있어야 한다
총의 방아쇠를 당긴다는 의미의 단어는 Trigger이다
즉 버튼을 크릭하였을때 할 것인가, 폼이 로딩될때 할 것인가..
아니면 속성값이 바뀌면 할 것인가..
혹은 어떤 정보가 들어오면 할 것인가..
라는 것을 관리하는 것이 Trigger개체인것이다

또한 Trigger는 여러개가 있을수 있으므로 집합체가 있다
즉 Triggers라는 집합체개체에서 관리하게 되는 것이고
해당 버튼의 하위 개체집합에 Triggers개체가 있다
<Button.Triggers>
...<EventTrigger RoutedEvent="Button.Click">
.......
.......
...</EventTrigger RoutedEvent="Button.Click">
</Button.Triggers>

여러종류의 Trigger개체중에서 EventTrigger라는 개체
즉 어떤 이벤트가 발생하면 격발(Trigger)하라는 구문을 작성하는 것이다
위에서는 Button을 크릭하면 실행하라는 것이고
무엇을 실행하냐 하면 위에서 말한 StoryBoard를 실행하라는 것이다
에니메이션은 시작하라는 것도 있을수있고
정지하라는 신호도 보낼수 있어야 하고
잠시 멈추라는 신호도 보낼수 있어야 할 것이고
잠시 멈추었으면 다시 그 상태에서 시작하라는 것이 있을 것이다
그중의 하나가
BeginStoryBoard
인것이다

<BeginStoryboard>
....<Storyboard>
........<DoubleAnimation Storyboard.TargetProperty="Height" To="100" Duration="0:0:05" AutoReverse="True" />
....</Storyboard>
</BeginStoryboard>

BiginStoryBoade태그 사이에 StoryBoard태그가 있고
그 안에 실제로 에니메이션을 하는 개체 DoubleAnimation개체가 있는 것이다
여기에서 Double은 속성값의 타입이 Double이고
어떤 값에서 어떤값까지 속성값이 변하게 한다는 이야기다
위의 경우는 버튼의 높이(Height)를 본래 그려진 높이(From 속성값의 생략)
어떤 높이까지..즉 To=100 까지 높이를 크게 하는데
어느 정도의 시간안에 그것이 이루어지느냐는 것이 중요한 것이다
Duration이라는 속성값을 0시간0분 05초 동안 이루어지라는 값을 준것이다
속도를 조정 하려면 이 값을 조정하면 되는 것이다
또한 높이가 100까지 갔다가 다시 본래의 높이값으로 돌아오게 하는 것은
AutoReverse속성값을 True로 주면 그렇게 되는 것이다
흥미로운 프로그래밍 방법인 것이다

아래화일로 실행해 보시면서 잘 관찰하면 흥미로울 것이다

***[LOG-IN]***

위의 내용을 VB로 코딩해 보자..
역시 VB로 해야 프로그래밍 답다..!!!
나중에는 위의 XAML문과 VB코딩과 적절히 조화를 이뤄가게 되는 셈이다
새로움에 도전하여보시기를..
어휴..아직 VBA도 못했는데.@#$@!!.
세상에 완성이라는 것은 없다
무엇하나를 완성하고 다른 것에 도전하겠다????
그냥 진행형 생활화가 되어야 하는 것..
생각을 폐쇄적으로 하면 죽을 때까지 다른 곳으로 확장 못한다
VB를 하면서 VBA에 영감을 주고..VBA를 하면서 VB에 영감을 주는 것이다
그래야 내공이 쌓이고 무언가 새로운 것을 배우겠다는 열정이 생기게 되고
그래야 인생이 건강하고 행복하다!!

코딩에 대한 이야기를 하기전에 좀 기초적인 것을 이야기하도록 하자
위에서 에니메이션을 맛보기로 한 것이고..

XAML은 Extensible Application MarkUp Language의 약자
지금 보고 있는 웹페이지는 HTML언어로 작성된 것이고
HTML은 Hyper Text MarkUp Language 의 약자이고
XML은 Extensible MarkUp Language의 약자이고
HTML이 정보와 서식을 한꺼번에 표현하는 언어이고
XML은 정보만 보관하는 정보관리에 대한 언어이고
이런 것들이 발전하여 XAML이 되었다고 보시면 될 것이다

텍스트문서 작성하듯이 프로그래밍을 하는 셈이다
하나의 개체를 Tag로 둘러쌓아서 표현하면 XAML언어의 엔진이
개체형식으로 알아서 변환을 시킨다고 보시면 좋을 것이다

하나의 버튼개체를 만들면서 기초를 이야기 하자

<Button>I'm Button</Button> 이라는 지극히 간단한 Tag로 둘러쌓인 텍스트는



와 같이 버튼이 만들어진다
그런데 윈도우폼에 하나 가득 버튼이 그려진 셈이다
위의 XAML문을 아래와 같이 확장해 보자

<Button VerticalAlignment="Top" Margin="10,10" Width="100" Height="30" HorizontalAlignment="Left"> I'm Button </Button>

VBA에서도 수도없이 속성값을 주었던 기억이 날 것이다
속성의 표현을 위와 같이 한 것이다
엑셀의 셀의 속성에도 모두 있는 내용들이고, 좀 다른 것이 있거나
이름이 좀 다른 이름으로 있다는 것 뿐이지 개체를 그리는 모두 같은 것이다
폭이 있어야 할것이고, 높이가 있어야 할 것이고
수평줄맟움이 있어야 할 것이고, 수직줄맞춤이 있어야 할 것이고
위에서 낯선것은 Margin이라는 것이 있을 것이다
버튼개체를 버튼을 담고 있는 개체와 간격을 유지시킨다는 것이다
XAML에서 위와 같이 시작Tag에 같이 표현하는 것을 Attribute라고 한다
속성을 Property라고도 하고 Attribute라고도 하지만 XAML에서는 Attribute
라고 부른다
또 Property로 표현하는 Syntax도 있으니 ..좀 있으면 이야기할 것이다
아무튼 위와 같은 문자열표현은 아래의 그림과 같이 구현된다
그냥 VBA에서 익숙하듯이 속성으로 알고 있으면 된다



참으로 흥미롭지 않은가..
그냥 자판에 뚝딱거리고 만들고 싶은 것을 줄줄이 작성하면
만들어진다

이제 윈도우의 Button, VBA의 Button과 다른 것은 무엇일까..
우선 맨위에서 에니메이션을 할때 보았듯이 회전을 한다는 것이다
아래와 같이 작성해 보자

<Button VerticalAlignment="Center" Margin="10,10" Width="100" Height="30" HorizontalAlignment="Left" Content="I'm Button"> <Button.RenderTransform> <RotateTransform CenterX="50" CenterY="50" Angle="45" /> </Button.RenderTransform> </Button>

기존의 윈도우와 다른 속성이 있다
속성밑에 또 속성이 있고..즉 속성이 개체를 만들고 이 개체의
속성이 또 개체를 만들고..Tree형식으로 자식들이 부모밑으로
줄기를 치는 흥미로운 구조인 것이다

왜 그렇게 복잡하냐..??
위에서 RederTransform이라는 속성이 있다
즉 RederTransform개제가 되는 셈이고 이 개체의 밑에는
다양한 도형의 모양을 변형시키는 개체(속성)들이 있는 것이다
좀더 다양한 표현을 하기 위하여 다양한 개체를 갖고 있다고 보면 되고
이것을 관리하려고 하니..Tag와 Tag사이에 또 Tag를 넣게 되는 표현이
되는 것이다
위의 RederTransform개체가 갖고 있는 개체의 모양을 변형시키는 것중에
회전을 시키는 일을 하는 개체가 RotateTransform이라는 것이 있고
이것은 속성(Attribute)을 CenterX, CenterY, Angle이라는 것을
기본적으로 갖고 있는 것..
이 말은 버튼의 회전중심축의 X좌표와 Y좌표, 그리고 이 회전축을
중심으로 몇도를 회전을 시킬것인지를 표현하는 Angle이 있게 되는 것이다

그래서 위의 XAML문은 아래와 같이 구현된다



기존의 윈도우나 UserForm에서는 생각도 못할 짓을 하는 셈이다
이제 이것을 연속동작으로 회전을 시켜 보자
즉 에니메이션을 시켜 보자

<Button VerticalAlignment="Center" Margin="10,10" Width="100" Height="30" HorizontalAlignment="Left" Content="I'm Button"> <Button.RenderTransform > <RotateTransform x:Name="myRotation" CenterX="50" CenterY="50" Angle="0" /> </Button.RenderTransform> <Button.Triggers> <EventTrigger RoutedEvent="Button.Click" > <BeginStoryboard> <Storyboard> <DoubleAnimation Duration="0:0:05" Storyboard.TargetName="myRotation" Storyboard.TargetProperty="Angle" From="0" To="360" RepeatBehavior="Forever" AutoReverse="True"/> </Storyboard> </BeginStoryboard> </EventTrigger> </Button.Triggers> </Button>

<Button>...</Button> 와 같이 Button태그내에 버튼의 다양한 작업을 하게 되는 것이다
속성만 주는 것이 아니라..움직이는 행동도 하게 하는 것이다
위의 Button.Triggers 라고 하는 것은 Button에서 발생하는 모든
이벤트를 표현할수 있는 셈이다
Button에서 변화가 생기는 것중에 속성값이 바뀔때도 있고
이벤트가 발생할때도 있을 것이다
그중에 이벤트가 발생할때 일을 시키는 것은
EventTrigger라는 Tag로 표현하는 것이다
버튼을 크릭하면 위에서 이야기하였던 에니메이션을 관리하는 StoryBoard
를 작동시키는 것이고 StoryBoard에는 에니메이션이 여러게 들어 갈수 있는 것이다
위의 것은 버튼이 회전을 하는 것이고
회전하면서 버튼의 바탕색을 변하게 하는 에니메이션도 같이 발생하게 해보자

<Button VerticalAlignment="Center" Margin="10,10" Width="100" Height="30" HorizontalAlignment="Left" Content="I'm Button"> <Button.Background> <SolidColorBrush x:Name="myColor" Color="Gray" /> </Button.Background> <Button.RenderTransform > <RotateTransform x:Name="myRotation" CenterX="50" CenterY="50" Angle="0" /> </Button.RenderTransform> <Button.Triggers> <EventTrigger RoutedEvent="Button.Click" > <BeginStoryboard> <Storyboard> <DoubleAnimation Duration="0:0:05" Storyboard.TargetName="myRotation" Storyboard.TargetProperty="Angle" From="0" To="360" RepeatBehavior="Forever" AutoReverse="True"/> <ColorAnimation To="Red" Duration="0:0:05" Storyboard.TargetName="myColor" Storyboard.TargetProperty="Color" /> </Storyboard> </BeginStoryboard> </EventTrigger> </Button.Triggers> </Button>

여기에서 보여드리고 싶은 것은 StoryBoard에는 여러개의 에니메이션을
동시에 작동 시킬수 있다는 것..StoryBoard는 여러개의 에니메니션개체를
갖고 있을 수 있다는 점
위에서는 하나는 회전시키고 , 다른 하나는 ColorAnimation이라는 이름의 개체
에니메이션시킬때는 어떤 것을 시켜야겠다는 TargetName이 있어야 한다
이 말은 버튼을 크릭하였을때, 버튼 자체가 에니메이션시키는 것이 아니라
다른 어떤 것도 에니메이션을 시킬수 있다는 소리다
TargetName을 지어주면 되는 것이다
그래서 위에 속성이 두개 만들어진것이다
하나는 RenderTransform, 또 하나는 BackGround 각각의 속성에는
또 자식개체가 들어 있다..각각의 자식개체가 에니메이션이 되는 Target이
되는 것이다..그래서 위에 보면

<RotateTransform x:Name="myRotation" CenterX="50" CenterY="50" Angle="0" />
<SolidColorBrush x:Name="myColor" Color="Gray" />

와 같이 이름을 지어준 것(빨강)을 에니메이션 개체의 TargetName속성에 주고
파랑색은 어떤 속성값을 변경시킬것인지를 지정해주는 TargetProperty 속성에 준것이다

사람이 사는 세상과 같이 만들어 보려고 노력을 무지하게 하는 셈이다
언제,어디서,누가,무엇을,어떻게,왜..라는 것이 모두 들어가는 것이
프로그래밍이니..프로그래밍은 사람을 똑똑하게 만든다

VB로 코딩하여 보자고 해놓고 XAML에 기본에 대하여 대강이야기 하였다
아래의 화일은 위의 XAML문 하나도 없이
그냥 코딩으로 처리하는 것을 해본다
설명은 모듈시트에 주석으로 처리했다

***[LOG-IN]***

참 흥미로운 프로그래밍 세상이 계속 진행 될 것이니..
엑셀,VBA와 상관 없잖아!!! 하지 마시고 관심을 갖으시기를...!!