Tech/Silverlight2009. 12. 26. 20:40

커맨드 패턴이 뭔지에 대한 설명은 생략하고 다짜고짜 들어가보도록 하겠습니다.

왜 커맨드 패턴인가?

보통 WPF/Silverlight에서는 Presentation Model 패턴(흔히 MVVM 패턴)을 써서 GUI(View)와 프로그램 상태(ViewModel)를 분리합니다. Binding 이라는 기술적인 개념 덕분에 xaml.cs 파일에는 코드 한 줄 쓰지 않고도 View와 ViewModel을 연결할 수가 있고, View와 ViewModel이 서로를 몰라도 되는 상황을 유지할 수 있습니다. 그런데 이건 보여주는 기능에만 해당되는 얘기일 뿐 사용자가 버튼을 클릭했을 때 발생하는 이벤트를 처리한다거나 하는 일을 위해서는 xaml.cs(View)에서 코드를 통해 ViewModel의 메서드를 호출해 줘야 합니다.

커맨드 패턴을 사용하면 View와 ViewModel의 분리 상태를 유지하면서 View에서 발생한 이벤트를 ViewModel로 알려줄 수 있게 됩니다.

준비 사항

Silverlight 4 이전 버전에서 커맨드 패턴을 사용하려면 SLExtensionsComposite Client Application Guidance(Prism) 라이브러리를 사용하면 됩니다. MS의 patterns & practices 그룹에서 발표한 Prism을 쓰고 싶었지만 단지 커맨드 패턴만을 쓰기 위해서는 프레임워크도 그렇고 문서도 그렇고 너무 방대해서 짧은 시간에 파악하기 힘들었습니다. 그래서 이번에는 SLExtensions를 사용해보도록 하겠습니다.

SLExtensions 다운로드 페이지에서 받을 수 있는 알파 릴리즈를 사용하면 Blend에서 프로젝트를 열였을 때 다음과 같은 에러가 발생하면서 XAML을 로드할 수 없게 됩니다.

A command with the same name '{0}' is already registered.

Blend에서 더미 데이터가 채워져 있는 GUI를 보면서 디자인 할 수 있다는 건 상당한 장점인데, 그러한 장점을 못쓰게 된다는 것은 뼈아픈 일이지요. 다행히 최신 소스 코드(현재 Changeset 35533)에서는 이 문제가 해결되어 있습니다.

일단 Source Code 페이지 우측의 Latest Version Download 링크에서 최신 버전 소스를 받습니다. 압축을 풀면 나오는 소스에서 trunk/SLExtensions/SLExtensions 폴더의 프로젝트를 빌드해서 사용하면 됩니다. 빌드된 dll 파일은 ClientBin 폴더에 생성됩니다.


다음 연재 : Commands in Silverlight with SLExtensions - 2

'Tech > Silverlight' 카테고리의 다른 글

Custom Animation in Silverlight  (1) 2010.01.06
Commands in Silverlight with SLExtensions - 2  (0) 2010.01.01
Silverlight Pixel Shader 개발 팁  (0) 2009.10.28
[Element Binding]  (0) 2009.10.12
Posted by wafe
Tech/WPF2009. 11. 12. 17:34
이전글 : [WPF 3D UI 구현하기 - 2]

이제 물체가 어떤 방식으로 빛을 반사하게 될 지를 결정하는 Material을 알아보도록 하자.
Material은 총 세 가지 종류로 되어 있다.
1. DiffuseMaterial
2. SpecularMaterial
3. EmissiveMaterial

Blend에서 한 번 확인해 볼까?



ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ..ㅋ.ㅋㅋㅋㅋㅋㅋㅋㅋ.....
ㅋ.
..
발광 재질 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 발광 ㅋㅋㅋㅋㅋㅋㅋㅋ ... ㅋ...ㅋ....

나만 재밌었나보다... -ㅅ-)... 어흠

여하튼, Blend에서도 저 3가지 종류의 Material을 설정할 수 있도록 되어 있다. 싱기방기.
내가 사용한 Material은 DiffuseMaterial인데 이 아이는 조명에 영향을 많이 받는다. 조명(Light)으로부터 들어오는 빛의 각도와 물체의 각도가 좁을수록 반사되는 빛이 많아지고, 각도가 클수록 반사되는 빛의 양이 적어진다. 때문에 빛을 덜 받는 부분은 자연스럽게 명암이 생긴다.
그런데 내가 만든 앞면 Panel은 평면이기 때문에 회전하지 않은 이상 정면에서 조명을 받게 되면 명암이 생길 이유가 없다. ㅎ.


<Viewport2DVisual3D.Material>
<DiffuseMaterial Viewport2DVisual3D.IsVisualHostMaterial="True" Brush="White"/>
</Viewport2DVisual3D.Material>

IsVisualHostMaterial을 이 곳에서 True로 설정해주어 쌩뚱맞다고 생각할지도 모르겠다.
이 아이에 대해 msdn에 물어보면

"재질이 대화형이어야 하는지 여부를 지정하는 값을 가져오거나 설정합니다."
http://msdn.microsoft.com/ko-kr/library/system.windows.media.media3d.viewport2dvisual3d.isvisualhostmaterial.aspx

라고 대답할 것이다. 즉 지금 표현할 2차원 물체의 재질이 사용자와 상호작용을 할 놈인지 아닌지를 설정해주는 것이라고 생각하면 될 것 같다.
이것을 false로 설정한다면 ? 직접 해 보면 알겠지만 안 보인다.
물체가 반사할 색상은 White로 설정하였다. 사실 Geometry를 이용해서 물체를 그린 것이 아니고 이미 앞면 Panel을 만들어 놓은 상태에서 그것을 불러오기 때문에 굳이 반사할 색상을 정해주지 않아도 된다.

이제 실제 나타날 물체의 정보를 적어주면 되는데...
아주 간단하다.
<Viewport2DVisual3D.Visual> 같은 Visual에 대해 선언할 필요도 없이 바로 그냥 물체를 나타내는 XAML코드를 적어주면 된다.

1
<local:FrontPanel x:Name="FrontPan"/>

새로운 UserControl을 추가 생성하여 그 곳에 앞면 Panel을 만든 후에 정보를 불러왔기 때문에 별다른 정의 없이 위와 같은 방법으로 로드하면 된다.
예를 들어, 버튼을 Visual로 설정하려고 한다면

1
<Button x:Name="myButton" Width="100" Height="30" Content="Ok" />

이와 같이 한 줄만 추가하면 될 것이다.

자, 이제 뒷면 Panel을 추가해줘야 한다. 비로소 내가 화면에 보여주고 싶은 애들은 다 끄집어 낸 거다. (고작 2개뿐이지만...)
이 아이도 앞면 Panel과 같은 방식으로 Viewport2DVisual3D를 사용하여 만들어주면 되는데, 다른 점은 Transform 에서 미리 Y축으로 180도 회전 시킨 상태여야 한다는 것이다.

1
2
3
<RotateTransform3D.Rotation>
<AxisAngleRotation3D Angle="180" Axis="0,1,0"/>
</RotateTransform3D.Rotation>

위와 같이 앞면 Panel과는 다르게 RotateTransform의 Angle 정보가 바뀌어져 있다.
이렇게만 설정해 주면 뒷면 Panel은 앞면 Panel과 반대 방향으로 뒤집혀져 있게 될 것이다.

-ㅁ-) 후아.. 드디어 두 Panel들을 3D로 변환시켰다.

끗--------------------------!!
... 이라고 말하고 싶지만 아직 한 가지가 남았다.
조명 =ㅍ=) !!!!!! ... OTL
이전에도 말했겠지만 조명이 없으면 그대는 내내 시커먼 물체를 멀뚱멀뚱 바라보는 수밖에 없을 것이다.

간단하게 조명을 붙여주자.

1
2
3
4
5
<ModelVisual3D x:Name="Light">
<ModelVisual3D.Content>
<DirectionalLight Color="White" Direction="0,0,-1"/>
</ModelVisual3D.Content>
</ModelVisual3D>

나는 Panel의 일부만을 비출 것도 아니기 때문에 DirectionalLight나 AmbientLight 둘 중에 하나를 고를 수 있는데, AmbientLight는 모든 각도에서 빛을 비추기 때문에 Panel을 회전시켰을 때에 명암이 발생하지 않게 된다. 때문에 여기선 DirectionalLight를 사용하기로 한다.

Light의 Direction은 0의 값을 가지면 비추지 않는다. Direction의 "0,0,-1"은 기본값이다. 빛의 세기를 조절하고 싶다면 살짝살짝 수치를 조정해주면 된다. Color는 조명색을 의미하는데 빨간색으로 변경하면 정육점 분위기를 연출할 수 있다.

자! 이제 조명을 비춰주었기 때문에 내가 원하는 Panel의 모습이 보인다!

만쉐~~!! ' ㅁ')/

이제 남은 것은 Panel에 있는 버튼을 이용하여 회전하는 문제인데,
이것은 Storyboard를 이용한 애니메이션 효과이기 때문에 여기선 언급하지 않겠다.

오늘은 여기까지~ ^ㅁ^)v


Posted by 알 수 없는 사용자