298 Results for 'Silverlight'

  1. 2009.07.28 VC-1 코덱과 H.264 코덱의 라이선스 (4)
  2. 2009.07.27 Rock 'n Ro!! (5)
  3. 2009.07.25 실버라이트 3로 마이그레이션 하기 (1)
  4. 2009.07.23 실버라이트 하기 좋은 날 #5, Smooth Streaming (1)
  5. 2009.07.18 실버라이트 하기 좋은 날 #4, Blend 가지고 놀기 (1)
  6. 2009.07.18 실버라이트 하기 좋은 날 #3, 개발환경 기초 (1)
  7. 2009.07.11 실버라이트 하기 좋은 날 #2 (4)
  8. 2009.07.11 See the Light! (1)
  9. 2009.07.10 Silverlight 3 RTW 폰트 렌더링 향상! (3)
  10. 2009.07.10 실버라이트 3 RTW에 새로 추가된 기능 몇 개[수정] (3)
  11. 2009.07.10 실버라이트 3 RTW 드디어 출시! (2)
  12. 2009.07.02 실버라이트 하기 좋은 날 #1 (6)
  13. 2009.06.22 실버라이트 무인설치[수정]
  14. 2009.06.11 Behaviors make me depressed. (1)
  15. 2009.06.09 DataBinding with Behaviors in SL3 (1)
  16. 2009.05.22 VS2008, VS10, Silverlight 2, 3 함께 살기
  17. 2009.05.17 DTFE2009 훈스닷넷 1세션 실버라이트 3 발표 자료 (3)
  18. 2009.05.13 DTFE2009 훈스닷넷 UX 세미나 - 실버라이트 3 가지고 놀기 예고편
  19. 2009.05.11 How about if DependencyObject could be a DataBinding target?
  20. 2009.05.09 Behaviors in Silverlight 2 (5)
  21. 2009.05.05 제1회 DevDcc 실버라이트3 발표자료 (3)
  22. 2009.04.19 DevDcc 1회 행사에 와주신 분들께 감사드려요. (5)
  23. 2009.04.07 데이터 바인딩#2 데이터 바인딩의 원리와 사용법 (1)
  24. 2009.04.05 스타크래프트 프로리그를 즐기는 방법 (5)
  25. 2009.04.05 Behavior를 실버라이트 2에서 사용하기 (5)
  26. 2009.04.04 블렌드의 희한한 이름 제한
  27. 2009.03.27 실버라이트 3의 새 기능 정리 (2)
  28. 2009.03.27 데이터 바인딩#1 맛보기
  29. 2009.03.26 실버라이트 3에 대한 생각 (2)
  30. 2009.02.25 [HOL#00] 핸즈 온 랩 시리즈 인덱스 (2)

최근에 VC-1 코덱을 사용하면 라이선스 비용때문에 도입을 못하겠다… 그래서 H.264를 선택했다…라는 얘기를 들었는데요, 저도 라이선스 관련은 제대로 모르지만 여튼 VC-1과 H.264모두 MPEG LA라는 곳에서 라이선스를 계약해야 하는 걸로 알고 있었거든요. 암튼 그간 실버라이트 하면서 VC-1과 H.264의 기술적 차이나 특성은 많이 봤지만 정작 중요한 라이선스 비용에 대한 정확한 얘기는 못 본 것 같아서 자료를 좀 찾아봤어요.

…아뿔싸 그런데 역시나 한글 자료는 없더군요 =_=
후우… 또 삽질 정신을 발휘하여 발번역 및 眞요약본 나갑니다.
이게 법적인 용어들과 경제 용어가 난무하다 보니 농담이 아니고 진짜 발번역인데다가 같은 말을 여러 번 반복하는 부분은 과감하게 생략한 부분도 많으니 혹시 실무에 사용하시려는 분은 꼭, 반드시 제대로 된 검토를 거치시길 바라고 번역상 심각하게 문제가 있는 부분은 알려주세요.

▼VC-1 코덱 라이선스 발번역 보기

아오 빡세… 근데 원문을 봐도 번역문을 봐도 솔직히 복잡하긴 마찬가지에요. 그래서 진짜 초 간단하게 표로 요약해 봤고요, 대략적인 비용 계산은 이 표를 이용해도 될 것 같아요.

 

두둥~~

아니 어째 이렇게 정리가 되는 내용을 베베꼬아 놨대요 그래. 일단 표로 만들고 주석을 다는게 훨씬 보기 좋구만…

어쨌든, 우리의 관심사는 실버라이트로 미디어 서비스를 제공할 때 비용이 어떡게 되느냐…겠죠? 그리고 궁극적인 답은 공짜로 쓸 수 있느냐 없느냐고요. 결론적으로는 ‘제한적으로’ 가능하다 에요. 위의 표에 따라 VC-1 코덱을 사용한 미디어로 서비스 할 때 무료로 이용할 수 있는 조건은 다음과 같이 정리할 수 있겠네요.

  • 사용자에게 한 건당 요금을 받지만 영상이 12분 이하일 때.
  • 사용자에게 기간 한정 또는 개수 한정으로 요금을 받지만 서비스 가입자가 10만명 이하일 때.
  • 사용자에게 직접적으로 요금을 받지 않는 인터넷 서비스일 때.
    (※단, 이 경우 광고 등의 수익 모델은 가능하며 2012년까지 한시적으로 적용됨)

네 사실 이 세 문장을 보기 위해 저런 캐삽질을 한 거죠.

그럼 H.264는 어떨까요? 이쪽도 해봐야 겠죠? 그.런.데. 진짜 하나하나 거의 다 똑같은 문구로 되어 있고 결정적으로 라이선스 비용도 완전히 동일해요. 제가 결코 귀찮아서 번역이랑 요약을 안하는게 아니고요. 핫핫!

한 가지 다른 점이 있다면 현재 VC-1의 라이선스 기간(주기)가 2012년까지인데 반해 H.264의 경우 2010년까지라는 거죠. 만약 인터넷으로 무료 서비스를 한다면 H.264의 경우 당장 내년 이후에는 라이선스 갱신을 고려해야 하고요, VC-1의 경우는 그럭저럭 2012년까지는 버틸 수 있다는 거죠. 물론 조항에 보면 ‘근거있는’ 조건으로 라이선스 조항이 변경될 가능성도 있지만요.

여튼 전적으로 제 해석에 따른 결론은 VC-1과 H.264의 ‘실제 서비스 비용’은 완전히 동일하다 이고요. 오류 지적은 웰컴 베리 쌩유~

마지막으로 번역한거 다운로드.


Posted by gongdo
본격 캐민망 실버라이트 쑈!
Gongdo the Guitar Hero!

(외국에 올린거라 촘 느리니 인내심을...)
예... 사실 5월달에 만들었는데 그간 민망함에 몸서리치다가 포스팅꺼리가 떨어져서 용기를 내서 올립니다.
그런거죠 뭐...
이 캐민망 영상을 참고 볼 수 있다면 아래쪽에 슬라이더도 조절해보세요.

이게 뭐하는 쌩쑈냐면 실버라이트 3에 추가된 픽셀셰이더 이펙트를 사용한 데모에요.
그냥 동영상 하나 아니냐고 하실지도 모르겠지만 사실은 앞뒤로 두 개의 동영상이 동시에 돌아가고 있고 그 중 앞에 있는 동영상에 크로마키효과를 사용하여 뒤에 있는 동영상과 섞은거에요.

여튼 자세한 설명은 생략하고 반응에 따라서(?) 나중에 다시 소개할지도 몰라요^^
관심 있는 분은 소스를 다운로드.

Posted by gongdo

언제나처럼 버전업이 되면 MSDN에 마이그레이션에 관한 거의 완벽한 가이드가 나오죠. 이 글도 Ensuring That Your Silverlight 2 Applications Work with Silverlight 3를 번역한 거에요.

계속해서 추가적인 문제가 발견되면 Silverlight SDK 팀블로그여기에 올라오고 있는데 7월 25일 현재 올라온 것까지 합쳐서 번역했어요.

 

1. 소개

이 글은 실버라이트 2와 실버라이트 3간에 실버라이트 런타임 및 실버라이트 툴에 어떤 변화가 있었는지 소개합니다. 이 글에서 소개하는 변화는 기존의 실버라이트 기반 애플리케이션이 이제 실패하거나 오작동하는 원인이 될 가능성이 있는 것에 집중하였고, 단순히 이번 릴리즈에서 추가되거나 향상된 기능은 제외 했습니다. 이 글은 크게 세 가지 섹션을 다룹니다.

  • 실버라이트 3 베타 이후의 Breaking Changes(※더 이상 지원되지 않아 빌드를 깨는 변화)
    실버라이트 3 베타 애플리케이션은 그리 많지 않으므로 이 섹션은 생략합니다.
  • 실버라이트 2 이후의 Breaking Changes
  • 업그레이드 Breaking Changes: 이 변경은 실버라이트 3로 재컴파일 하지 않는 한 문제를 일으키지 않을 것입니다.
주의:
이 문서의 정정이나 추가는 Silverlight SDK 팀블로그를 참고. 

2. 목차

  1. 소개
  2. 목차
  3. 실버라이트 3 베타 이후의 Breaking Changes(※생략)
  4. 실버라이트 2 이후의 Breaking Changes
    1. System.Web.Silverlight.dll이 Silverlight SDK에서 제거됨.
    2. 실버라이트 애플리케이션은 브라우저 줌에 정상적으로 반응함.
    3. Popup 탭 키 변경
    4. ComboBox 팝업 클리핑 수정(fixed)
    5. 실버라이트가 Popup.RenderTransform이 변했을 때 항상 팝업을 새로 그림.
    6. ContentPresenter.Content = "string"이 더 이상 ContentTemplate 속성을 변경하지 않음.
    7. ContentControl이 빈 ContentTemplate을 사용할 때 Content를 무시함.
    8. ContentControl.Content를 설정하는 것이 불필요한 OnApplyTemplate 호출을 발생시키지 않음.
    9. ComboBox와 ContentControl은 ItemsSource가 TypeConverter가 붙은 enum으로 설정될 때 숫자가 아닌 문자를 표시함.
    10. 선택된 아이템이 없는 ComboBox에서는 추가적인 키 입력을 받아야 두 번째 아이템이 선택됨.
    11. HorizontalScrollBarVisibility와 VerticalScrollBarVisibility를 ComboBox와 ListBox용 스타일에서 설정할 수 있음.
    12. ListBoxItem.HorizontalContentAlignment가 정상적으로 적용됨.
    13. ListBoxItem.Style이 ListBox.ItemContainerStyle보다 우선시됨.
    14. ListBox안에서 탭을 하면 ListBox의 다음 아이템이 아닌 ListBox의 다음 컨트롤로 이동.
    15. PasswordBox/TextBox의 TemplatePart 정의를 제거.
    16. TextBox의 TextAlignment가 TextBox가 아닌 문서에 대하여 작용함.
    17. 읽기 전용 TextBox의 색상이 변경됨.
    18. ENTER키는 Button.ClickMode가 기본 값인 Release(KeyUp)일 때만 작동함.
    19. Slider 컨트롤의 히트 테스트 영역이 보이는 것과 일치함.
    20. 잘못된 URL 형식이 포함된 clientaccesspolicy.xml이 파일 전체에 영향을 주지 않고 그 URL만 무시함.
    21. Opacity 변경이 항상 새로 그려지지 않았던 버그 수정.
    22. DataBinding을 할 때 프로퍼티 세터(setter)가 반드시 public이어야 함.
    23. SetBinding()을 호출한 이후의 Binding.Path 변경은 허용되지 않음.
    24. Image.Source가 초기화 되지 않았을 때 null을 반환함.
    25. GetValue(ImageBrush.ImageSource)가 BitmapImage가 아닌 문자열을 반환함.
    26. 크로스 도메인의 .xap을 가져오는 <asp:Silverlight>가 JavaScript 에러를 냄.
    27. NotifyCollectionChangedEventHandler.Target이 이제 ItemsControl이 아닌 WeakCollectionChangedEventListener를 반환함.
  5. 업그레이드 Breaking Changes
    1. OpenFileDialog.ShowDialog()는 오직 사용자가 일으킨 이벤트에서만 열림.
    2. 탭 동작 처리와 연관된 콜백이 비동기에서 동기로 변경됨.
    3. Popup 안에서 일어난 마우스 이벤트가 전체 애플리케이션이 아닌 팝업 영역에 대한 위치를 제공함.
    4. Popup이 하나의 부모만 갖게 됨.
    5. Popup안의 네임스콥(Namescope)이 정확하게 동작함.
    6. FindElementsInHostCoordinates가 Popup도 검색함.
    7. ItemsControl안의 Item이 교체되는 것과 연관된 이벤트가 제거됨.
    8. ScrollViewer가 스크롤바의 위치를 ScrollableWidth/ScrollableWidth까지 축소함.
    9. Rectangle과 Ellipse의 Stretch가 설정되었고 Height 또는 Width가 설정되지 않으면 표시됨.
    10. TextBlock, TextBox 및 PasswordBox의 Width가 올림 됨.
    11. TextBlock.FontFamily=null은 ArgumentNullException을 던짐.
    12. 템플릿에서 Run 엘리먼트 사이에 있는 공백이 더 이상 렌더링되지 않음.
    13. RadioButton.GroupName은 템플릿 바깥쪽의 RadioButton을 검색.
    14. ComboBox의 콘텐트에 IsHitTestVisible="False"가 먹힘.
    15. TextBox에 Opacity 프로퍼티가 작동함.
    16. FrameworkElementAutomationPeer 생성자에 null 파라미터를 주면 NullReferenceException을 던짐.
    17. HyperlinkButton이 이제 실버라이트가 들어있는 전체 윈도가 아닌 IFRAME에 대해 내비게이션 동작함.
    18. 실버라이트 2 이상의 애플리케이션이 XAP 파일 확장자를 갖지 않을 때 base URI 문제를 정정함.
    19. Application.Current.Host.Source는 .xap URL이 쿼리 스트링을 포함할지라도 절대 URL을 반환함.
    20. ResourceDictionary enum 버그가 수정됨.
    21. ReadOnlyObservableCollection이 System.Windows.Controls.Data.dll에서 System.Windows.dll로 옮김.
    22. DataGridEndingEditEventArgs가 Silverlight SDK에서 제거됨.
    23. PollingDuplexHttpBinding 변경점.
    24. 이벤트 핸들러를 제거할 때 버그 수정.
    25. <Cursor>대신 <Cursors>를 허용하는 버그 수정.
    26. XAML에서 커스텀 첨부 프로퍼티는 xmlns 접두사를 써야 함.
    27. 서브클래스 컨트롤이 리소스를 잘못 로드할 수 있는 버그 수정.
    28. 경로에 있는 자식 오브젝트가 null일 경우 ValueConverter가 호출되지 않는 버그 수정.
    29. .xap의 바깥 쪽에 있는 리소스를 가리키던 상대 URL가 HTML page가 아닌 .xap 파일에 대해 작용함.
    30. SetBinding() 이후에 Binding 속성을 설정하는 것은 더 이상 지원하지 않음.
    31. ContentPresenter의 자식은 오직 하나의 부모를 가짐.
    32. Thumb 컨트롤이 이제는 그 부모에 대해서가 아니라 절대 위치를 기준으로 드래그를 계산.
    33. DataGrid가 이제는 첫 번째 아이템을 기본으로 선택하지 않음.
    34. DataGrid에서 마지막 아이템이 HorizontalScrollBarVisibility="Auto"일 때 키보드를 사용할 수 없는 버그 수정.

3. 실버라이트 3 이후의 Breaking Changes(※생략)

4. 실버라이트 2 이후의 Breaking Changes

이 섹션에서 설명하는 변경 사항은 실버라이트 2 애플리케이션의 동작을 망가뜨릴 수 있습니다. 이 중의 많은 사항은 사실 버그 수정입니다. 그렇다 하더라도, 실버라이트 2 애플리케이션이 이 버그를 피하기 위해 워크어라운드를 적용했다면, 애플리케이션이 올바로 동작되도록 이 워크어라운드를 제거해야 할 것입니다.

4.1 System.Web.Silverlight.dll이 Silverlight SDK에서 제거됨.

ASP.NET Silverlight 및 MediaPlayer 컨트롤이 Silverlight 3 SDK에서 제거되었습니다. 이들은 System.Web.Silverlight.dll이라는 이름의 서버 어셈블리에 포함되고 보통 테스트 웹 사이트의 Bin폴더에서 얻을 수 있습니다.

기존의 실버라이트 2 웹 사이트는 각 웹 애플리케이션의 Bin 폴더에서 Silverlight.Web.Silverlight 어셈블리를 가지고 있기 때문에(심지어 실버라이트 2 SDK가 언인스톨 되어도) 계속 동작 할 것입니다.

기존 프로젝트를 실버라이트 3로 업그레이드 할 때, 대부분의 경우 반드시 이 컨트롤을 동일한 역할을 하는 <object>태그로 교체해야 합니다. 예를 들어 <asp:Silverlight>는 다음과 같이 수정할 수 있습니다.

<div id="silverlightControlHost">
    <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
     <param name="source" value="{XAP_FILE}"/>
         <param name="onerror" value="onSilverlightError" />
         <param name="background" value="white" />
         <param name="minRuntimeVersion" value="{BUILD}" />
          <param name="autoUpgrade" value="true" />
          <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v={BUILD}" style="text-decoration: none;">
               <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
           </a>
       </object>
        <iframe id="_sl_historyFrame" style='visibility:hidden;height:0;width:0;border:0px'></iframe>
</div>

기존의 실버라이트 애플리케이션은 각 웹 애플리케이션의 Bin 폴더에서 System.Web.Silverlight 어셈블리를 얻으려고 할 것입니다. 때문에 실버라이트 3 SDK로 업그레이드 하여도 이 로컬 어셈블리를 제거하지 않을 것이며 애플리케이션은 동작할 것입니다. 개발자는 실버라이트 3용으로 적절한 버전 플래그를 설정할 것입니다.

  • 클라이언트에서 기존의 fwlink가 실버라이트 3를 가리키도록 해야함.
  • System.Web.Silverlight 어셈블리를 GAC에 등록한 개발자라면 GAC에서 수동으로 제거해야 함.

개발자가 새 애플리케이션을 만들 때는 최신의 object 태그 및 다른 마크업을 포함한 템플릿을 사용하길 바랄 것입니다.

  • 개발자는 System.Web.Silverlight 어셈블리를 수동으로 추가하고 서버 컨트롤을 사용할 수도 있습니다. 그러나, 이 컨트롤은 최신의 설치 로직을 지원하지 않고, 실버라이트 히스토리 지원에 필요한 iframe 등을 렌더링 하지 않을 것입니다.

ASP.NET 서버 컨트롤을 실버라이트 3로 마이그레이션 하려면 ASP.NET Server Controls for Silverlight in the Silverlight SDK를 참고하세요.

4.2 실버라이트 애플리케이션은 브라우저 줌에 정상적으로 반응함.

실버라이트 애플리케이션(기존과 새 버전 모두)은 현재 상태에 따라 브라우저 줌에 대해 응답할 수 있는 기회를 가집니다. 실버라이트 애플리케이션은 애플리케이션이 Resized이벤트를 핸들링하지 않는다면 기본으로 줌을 할 것입니다. 줌은 루트 엘리먼트의 가상의 부모에 대해 RenderTransform = new ScaleTransform()을 적용한 것과 동일합니다.

애플리케이션은 다음의 새 API를 사용하여 이 동작을 변경할 수 있습니다.

  • System.Windows.Interop.Content의 Zoomed 이벤트와 ZoomFactor 프로퍼티. (Content 클래스는 보통 App.Current.Host.Content로 사용)
  • 실버라이트 플러그인의 EnableAutoZoom 파라미터.

 

4.3 Popup 탭 키 변경

실버라이트 2에서 포커스가 팝업 안에 있고 TAB 키를 눌렀다면, 포커스가 실버라이트 영역을 벗어나 브라우저로 갑니다. 다른 컨트롤이 팝업에 있어도 무시됩니다. 실버라이트 3에서는 탭 동작이 팝업 내부를 먼저 돕니다. 만약 이 전 동작대로 작동하길 바란다면 Popup의 루트에서 TabNavigation="Cycle"로 설정하면 됩니다.

 

4.4 ComboBox 팝업 클리핑 수정(fixed)

실버라이트 2에서 ComboBox 팝업 안에 수직 스크롤바가 있을 경우 팝업이 ComboBox 자신보다 더 넓었고, 팝업이 스크롤바의 너비에 따라 너무 좁았습니다.

  

이 실버라이트 2 버그를 워크어라운드를 써서 ComboBox 아이템의 크기를 늘려 해결하였다면, 실버라이트 3에서는 원치 않는 공간을 더 차지하게 될 것이고 아마도 기존의 워크어라운드를 제거하고 싶을 것입니다.

 

4.5 실버라이트가 Popup.RenderTransform이 변했을 때 항상 팝업을 새로 그림.

실버라이트 2에서 실버라이트는 Popup.RenderTransform이 변경되었을 때 항상 다시 그리지 않았습니다. 실버라이트 3에서 이 버그가 수정되었습니다.

 

4.6 ContentPresenter.Content = "string"이 더 이상 ContentTemplate 속성을 변경하지 않음.

전에는 ContentPresenter.Content를 문자열로 설정하면 호출된 ContentPresenter.ContentTemplate에서 null이 아닌 문자열 값을 보게 될 것입니다. 이제는 ContentPresenter.Content를 문자열로 설정하여도 더 이상 ContentTemplate 속성을 변경하지 않습니다. 이 변경이 완료되어 ContentPresenter.Content는 한 번 문자열로 설정한 다음 다시 설정할 수 없습니다.

이 동작은 ContentPresenter에 해당하는 것이지 ContentControl이 아님에 주의하세요. ContentPresenter는 일반적으로 다음 XAML처럼 오직 컨트롤 템플릿의 내부에서만 사용됩니다.

<ContentPresenter
  Content="{TemplateBinding Content}"
  ContentTemplate="{TemplateBinding ContentTemplate}"
  HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
  VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
  Margin="{TemplateBinding Padding}"/>

 

4.7 ContentControl이 빈 ContentTemplate을 사용할 때 Content를 무시함.

실버라이트 2에서 ContentControl(예를 들어 Button)에 빈 ContentTemplate을 설정하면 컨트롤은 템플릿을 무시하고 ContentPresenter를 사용하여 표시할 것입니다. 예를 들어 실버라이트 2에서 다음 코드는 "ABC"를 표시합니다.

   <ContentControl Content="ABC">
        <ContentControl.ContentTemplate>
            <DataTemplate></DataTemplate>
        </ContentControl.ContentTemplate>
  </ContentControl>

이 문제는 실버라이트 3에서 수정되었고 이 코드는 이제 아무 내용도 표시하지 않습니다.

 

4.8 ContentControl.Content를 설정하는 것이 불필요한 OnApplyTemplate 호출을 발생시키지 않음.

실버라이트 2에서 ContentControl.Content를 세팅하면 OnApplyTemplate이 매번 호출되었습니다. 심지어 ContentControl.ControlTemplate이 설정되었어도 호출되었습니다. 실버라이트 3에서는 OnApplyTemplate은 ContentControl.ControlTemplate을 처음으로 설정될 때 한 번만 호출됩니다.

 

4.9 ComboBox와 ContentControl은 ItemsSource가 TypeConverter가 붙은 enum으로 설정될 때 숫자가 아닌 문자를 표시함.

실버라이트 2에서 ComboBox의 ItemsSource 속성에 Enum을 넣으면 ComboBox는 Enum의 이름이 아닌 수치 값을 표시합니다. 예를 들어,

enum MyEnum { First, Second, Third }
//...
MyComboBox.ItemsSource = new MyEnum[] { MyEnum.First };

이 코드는 "First"가 아니라 "1"을 표시합니다. 실버라이트 3에서는 수정되어 이제 문자열 값이 표시됩니다.

 

4.10 선택된 아이템이 없는 ComboBox에서는 추가적인 키 입력을 받아야 두 번째 아이템이 선택됨.

실버라이트 2에서 선택된 아이템이 없는 ComboBox를 열면 첫 번째 아이템이 선택되지도 않았으면서 포커스를 가집니다. 그래서 첫 번째 다운 키가 포커스와 선택을 두 번째 아이템으로 옮깁니다.

실버라이트 3에서는 ComboBox가 열렸을 때 첫 번째 아이템이 포커스를 갖지 않습니다. 첫 번째 키 입력은 첫 번째 아이템을 선택하고 포커스를 설정하며 두 번째 아이템은 두 번째 다운 키를 입력해야 포커스와 선택이 이동합니다.

 

4.11 HorizontalScrollBarVisibility와 VerticalScrollBarVisibility를 ComboBox와 ListBox용 스타일에서 설정할 수 있음.

실버라이트 2에서 이 프로퍼티는 생성자에서 내부적으로 설정되었으며 스타일의 값을 덮어 썼습니다. 이 문제가 수정되었습니다.

 

4.12 ListBoxItem.HorizontalContentAlignment가 정상적으로 적용됨.

실버라이트 2에서 ListBoxItem의 기본 템플릿을 사용할 때 HorizontalContentAlignment가 무시되었습니다. 이 문제가 수정되었습니다.

 

4.13 ListBoxItem.Style이 ListBox.ItemContainerStyle보다 우선시됨.

실버라이트 2에서 ListBoxItem.Style을 설정한 후 코드에서 ListBox.ItemContainerStyle을 설정하면 올바르지 않게 전에 설정한 ListBoxItem.Style을 덮어 씁니다. 이 문제가 수정되었습니다.

 

4.14 ListBox안에서 탭을 하면 ListBox의 다음 아이템이 아닌 ListBox의 다음 컨트롤로 이동.

실버라이트 2에서 ListBox안에서 TAB키를 누르면 다음 컨트롤이 아닌 다음 ListBox 아이템으로 이동했습니다. 이제 탭이 다른 플랫폼과 동일하게 동작합니다.

 

4.15 PasswordBox/TextBox의 TemplatePart 정의를 제거.

실버라이트 2에서 PasswordBox와 TextBox는 실제로는 가지고 있지 않은 많은 수의 [TemplatePart] 어트리뷰트로 컨트롤의 파트를 지정하였습니다. 이 어트리뷰트가 실버라이트 3에서는 제거되었습니다.

 

4.16 TextBox의 TextAlignment가 TextBox가 아닌 문서에 대하여 작용함.

실버라이트 2에서 TextBox의 텍스트는 문서에 기반하여 가운데 정렬하지 않고 TextBox의 Width 프로퍼티에 기반하여 가운데 정렬했습니다. 이것은 올바르지 않은 가운데 정렬이었습니다. 예를 들어 다음과 같이 가운데 정렬된 텍스트를 가정합시다.

실버라이트 2에서는 긴 텍스트를 타이핑하면 TextBox는 다음과 같이 표시됩니다.

실버라이트 3에서는 이 동작을 바로 잡았습니다. 올바른 동작은 "ABC"가 전체 문서의 가운데에 위치해야 하지 문서의 보이는 부분에 대해서 가운데 정렬되는 것이 아닙니다. 이 변경은 전체 텍스트의 크기에 영향을 주지는 않습니다. 그리고 사용자가 필요하다면 스크롤을 사용하여 뷰포인트를 가운데 정렬된 텍스트쪽으로 옮길 수 있습니다.

 

4.17 읽기 전용 TextBox의 색상이 변경됨.

실버라이트 2에서 읽기 전용 텍스트 박스는 수정 가능한 텍스트 박스와 별 차이가 없었습니다.

 

4.18 ENTER키는 Button.ClickMode가 기본 값인 Release(KeyUp)일 때만 작동함.

만약 애플리케이션이 ClickMode를 Press로 변경했다면 클릭 핸들러가 (클릭)재실행의 원인이 되는 코드를 실행하지 않습니다.

 

4.19 Slider 컨트롤의 히트 테스트 영역이 보이는 것과 일치함.

실버라이트 2에서 슬라이더를 길게 만들었다면 슬라이더의 파트가 아닌 것처럼 보이는 영역을 클릭할 수 있었습니다.

 

4.20 잘못된 URL 형식이 포함된 clientaccesspolicy.xml이 파일 전체에 영향을 주지 않고 그 URL만 무시함.

실버라이트 2에서 잘못된 URL은 나머지 clientaccesspolicy.xml을 무시하게 했습니다. 이 문제가 수정되었습니다.

 

4.21 Opacity 변경이 항상 새로 그려지지 않았던 버그 수정.

여러 사정으로 실버라이트 2에서 Opacity가 변경되었을 때 콘텐트를 다시 그리지 않았습니다. 이 문제가 수정되었습니다.

 

4.22 DataBinding을 할 때 프로퍼티 세터(setter)가 반드시 public이어야 함.

실버라이트 데이터 바인딩은 일반적으로 프로퍼티와 타입이 public이어야 합니다. 실버라이트 2에서는 public getter와 private setter를 가진 프로퍼티가 데이터 바인딩이 가능했습니다. 이 문제가 수정되었습니다.

 

4.23 SetBinding()을 호출한 이후의 Binding.Path 변경은 허용되지 않음.

실버라이트 2에서 SetBinding 호출이 끝났지만 DataContext가 설정되기 전이라면 Binding.Path를 설정할 수 있었습니다. 예를 들어,

Binding binding = new Binding();
myElement.SetBinding(HeightProperty, binding);
binding.Path = new PropertyPath("propertyname");
myElement.DataContext = …;

실버라이트 3에서는 한번 SetBinding이 호출되면 Path 속성을 더 이상 수정할 수 없으며 위의 코드는 다음과 같이 수정되어야 합니다.

Binding binding = new Binding();
binding.Path = new PropertyPath("propertyname");
myElement.SetBinding(HeightProperty, binding);
myElement.DataContext = …;

만약 Path가 SetBinding()이 호출된 후에 변경되면 실버라이트 3는 애플리케이션이 어떤 버전의 실버라이트에서 컴파일 되었냐에 따라 동작합니다. 실버라이트 3에서 컴파일되었다면 이 코드는 예외를 날리게 됩니다.

 

4.24 Image.Source가 초기화 되지 않았을 때 null을 반환함.

실버라이트 2에서 Image또는 ImageBrush.Source 프로퍼티가 설정되기 전에 접근하면 빈 BitmapImage를 생성하여 반환하였습니다. 실버라이트 3에서는 해당 프로퍼티가 설정되지 않았다면 null을 반환합니다.

 

4.25 GetValue(ImageBrush.ImageSource)가 문자열이 아닌 BitmapImage를 반환함.

실버라이트 2에서 다음 코드는 문자열을 반환했습니다.

myImageBrush.GetValue(ImageBrush.ImageSourceProperty);  // returns a string

실버라이트 3에서는 정상적으로 BitmapImage 오브젝트를 반환합니다.

 

4.26 크로스 도메인의 .xap을 가져오는 <asp:Silverlight>가 JavaScript 에러를 냄.

생략

 

4.27 NotifyCollectionChangedEventHandler.Target이 이제 ItemsControl이 아닌 WeakCollectionChangedEventListener를 반환함.

실버라이트 2에서 NotifyCollectionChangedEventHandler.Target이 ItemsControl을 반환했지만 실버라이트 3에서는 WeakCollectionChangedEventListener를 반환합니다.

 

5. 업그레이드 Breaking Changes

실버라이트 팀은 실버라이트 2에 있던 많은 버그를 실버라이트 3에서는 고치고 싶었습니다. 그러나, 몇몇 버그를 수정함으로써 기존의 실버라이트 2의 일부가 동작하지 않을 가능성이 있습니다. 이 문제를 넘어가려면, 실버라이트 개발자는 잠재적인 문제점이 있는 변경 사항을 “변칙 모드(quirk mode) 변경”으로 정할 수 있습니다. 변칙 모드 변경은 애플리케이션이 실버라이트 2용으로 디자인되었다고 감지했을 때에는 실버라이트 3 런타임이 강제되지 않는다는 것을 의미합니다. 이 때 실버라이트 3는 실버라이트 2 애플리케이션이 실행될 때 실버라이트 2의 “버그 호환”이 되도록 합니다. 어쨌든 이 섹션에서 설명하는 변경은 기존의 애플리케이션을 실버라이트 3용으로 재컴파일 했을 때만 적용될 것입니다.

다음 그림처럼 만약 애플리케이션의 RuntimeVersion이 실버라이트 2를 가리킨다면, 런타임은 “변칙 모드”가 됩니다. 변칙 모드일 때 런타임은 변칙 모드 변경 사항과 관련된 동작을 실버라이트 2에 맞출 것입니다.

 

위의 그림에서 실버라이트 3 런타임은 애플리케이션이 실버라이트 2용으로 디자인 되었는지 여부를 RuntimeVersion을 사용하여 알아냅니다. RuntimeVersion은 .xap 파일 안에 있는 AppManifest.xaml 파일의 어트리뷰트로 설정됩니다.

<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" EntryPointAssembly="ElevatorSilverlight"
            EntryPointType="ElevatorSilverlight.App"
            RuntimeVersion="2.0.31005.0">
  <Deployment.Parts>

RuntimeVersion은 애플리케이션을 컴파일한 개발자의 컴퓨터에 있었던 실버라이트의 버전을 말합니다.

 

5.1 OpenFileDialog.ShowDialog()는 오직 사용자가 일으킨 이벤트에서만 열림.

보안상의 이유로 OpenFileDialog.ShowDialog()는 사용자가 일으킨 이벤트(MouseLeftButtonDown/Up이나 KeyDown/Up)를 처리하는 동안에만 호출할 수 있습니다. 혹은 버튼을 클릭하거나 체크 박스를 클릭할 때 발생하는 이벤트에서 파생될 때에도 가능합니다. 이제 실버라이트는 다른 대부분의 브라우저나 플러그 인과 같은 동작을 합니다.

 

5.2 탭 동작 처리와 연관된 콜백이 비동기에서 동기로 변경됨.

실버라이트 2에서 페이지에 있는 마지막 컨트롤위에서 탭을 할 때 버그가 있었습니다. 이 버그를 수정하면서 생긴 부작용은 탭 처리와 관련된 GotFocus 이벤트와 같은 콜백이 비동기에서 동기로 변경되었다는 점입니다. (“비동기”란 사실은 PostMessage를 말합니다. 이는 현재 메시지가 처리된 직후 같은 스레드에서 동작합니다.) 이것은 Breaking change입니다. 왜냐하면 실버라이트에서 비동기 이벤트를 처리하는 중에는 HTML DOM으로 호출할 수 없기 때문입니다. 이 동작은 WPF에 있는 재진입(reentrancy) 제한의 실버라이트 버전입니다. 변칙 모드에서는 애플리케이션이 비동기 탭 처리를 할 것이며 이는 페이지의 가장 마지막 컨트롤에서 잘 동작하지 않을 것입니다.

 

5.3 Popup 안에서 일어난 마우스 이벤트가 전체 애플리케이션이 아닌 팝업 영역에 대한 위치를 제공함.

Popup 안에 있는 엘리먼트가 마우스 이벤트를 수신한다고 가정해 봅시다.

실버라이트 2에서 MouseButtonEventArgs.GetPosition()으로 얻은 좌표는 해당 실버라이트 플러그인에 대한 상대 좌표가 됩니다. 심지어 애플리케이션이 해당 엘리먼트에 대한 상대 좌표를 요청하더라도 그렇게 됩니다. 이 문제가 실버라이트 3에서는 수정되었습니다.

 

5.4 Popup이 하나의 부모만 갖게 됨.

실버라이트 2에서 여러가지 이유로 한 Popup이 두 개의 부모를 가질 수도 있었습니다. 실버라이트 3는 Popup에 오직 하나의 부모만을 허용합니다.

 

5.5 Popup안의 네임스콥(Namescope)이 올바로 동작함.

실버라이트 2는 Popup안에 있는 이름붙은 아이템이 Popup 되었을 때 잘못된 네임스콥을 설정하는 버그가 있었습니다. 자식이 자기 자신의 네임스콥을 가졌습니다 (예를 들어 자식이 XamlReader.Load로 생성됨). 이는 FindName()과 Storyboard.TargetName으로 찾아야 할 엘리먼트를 찾을 수 없거나 찾으면 안될 엘리먼트를 찾게 되었습니다 (실버라이트가 잘못된 네임스콥을 검색하므로). 어떤 경우 FindName()이 트리에서 제거된 엘리먼트를 찾았습니다. 이 문제가 실버라이트 3에서 수정되었습니다. 올바른 네임스콥 동작은 팝업이 트리에 실제로 올라왔고 팝업 되었을 때, 자식은 네임스콥의 오너가 아니며, 팝업의 자식들은 팝업 부모의 네임스콥에 일부가 됩니다. 그렇지 않은 경우 팝업의 자식들은 Popup.Child에 붙은 네임스콥에 들어있어야 합니다.

 

5.6 FindElementsInHostCoordinates가 Popup도 검색함.

실버라이트 2에서 FindElementInHostCoordinates가 Popup안은 검색하지 않았습니다. 이 문제가 수정되었습니다.

 

5.7 ItemsControl안의 Item이 교체되는 것과 연관된 이벤트가 제거됨.

실버라이트 2에서 ItemsControl에 있는 아이템을 교체하면 세 개의 이벤트-Remove, Add, Replace-를 만듭니다. 이 동작은 WPF와 호환되지 않고 이에 대해 코딩하기도 어렵습니다. Remove와 Add 이벤트를 받았을 때 이것이 잔짜로 교체하여 진행되는 것인지 알 수 없습니다. 실버라이트 3에서는 오직 Replace 이벤트만 발생합니다.

 

5.8 ScrollViewer가 스크롤바의 위치를 ScrollableWidth/ScrollableWidth까지 축소함.

이 결과, ScrollViewer에 있는 컨텐트의 너비와 높이는 레이아웃 계산 작업이 완료될 때까지 0이 됩니다.

 

5.9 Rectangle과 Ellipse의 Stretch가 설정되었고 Height 또는 Width가 설정되지 않으면 표시됨.

실버라이트 2에서 Stretch!=UniformToFill이고 너비나 높이가 설정되지 않은 Rectangle이나 Ellipse가 ContentControl에 있으면 오브젝트가 렌더링되지 않았습니다. 실버라이트 3에서는 Rectangle이나 Ellipse의 Stretch가 None이 아닐 경우 렌더링됩니다.

 

5.10 TextBlock, TextBox 및 PasswordBox의 Width가 올림 됨.

실버라이트 2에서 PasswordBox, TextBlock 및 TextBox의 크기가 자동으로 조절되게 하면 마지막 문자의 일부가 잘리는 현상이 있었습니다. 텍스트의 실제 길이가 정수가 아니고 소수 부분이 .5보다 작을 경우 그렇습니다. 예를 들어, 텍스트 길이가 96.34로 측정되면 96.00으로 내림 처리하고 TextBlock은 이 텍스트를 표시할 충분한 공간을 확보하지 않았습니다. 이제는 올림을 하기 때문에 애플리케이션의 레이아웃에 영향을 줍니다.

 

5.11 TextBlock.FontFamily=null은 ArgumentNullException을 던짐.

이제는 ArgumentNullException을 던집니다.

 

5.12 템플릿에서 Run 엘리먼트 사이에 있는 공백이 더 이상 렌더링되지 않음.

템플릿내에서 실버라이트 2는 암시적으로 엘리먼트 간에 공백을 삽입했기 때문에 <TextBlock><Run Text="Hel"/><Run Text="lo"/></TextBlock>이 "Hel_lo"(_는 공백)가 됩니다. 실버라이트 3에서는 이 공백을 렌더링하지 않습니다.

 

5.13 RadioButton.GroupName은 템플릿 바깥쪽의 RadioButton을 검색.

실버라이트 2에서 RadioButton.GroupName을 템플릿 안에서 사용한다면 실버라이트는 다른 RadioButton을 해당 템플릿 안에서만 검색합니다. 이 동작은 WPF와 다르고 다른 많은 유용한 시나리오를 어렵게 만듭니다. 실버라이트 3에서는 RadioButton이 템플릿 바깥쪽도 잘 검색합니다.

 

5.14 ComboBox의 콘텐트에 IsHitTestVisible="False"가 먹힘.

실버라이트 2에서 ComboBox안에서 선택된 아이템이 마우스 이벤트를 받았습니다. 이 동작은 ComboBox가 마우스 오버 상태에서 비주얼을 올바로 표시하는데 방해가 되었습니다. ComboBox는 이제 컨트롤 템플릿 내부적으로 ContentPresenter를 IsHitTestVisible="False"로 설정합니다. ComboBox자신은 여전히 마우스 이벤트를 받습니다.

 

5.15 TextBox에 Opacity 프로퍼티가 작동함.

실버라이트 2에서 Opacity 프로퍼티가 무시되었습니다 (항상 1로 처리됨). 이 문제가 수정되었습니다.

 

5.16 FrameworkElementAutomationPeer 생성자에 null 파라미터를 주면 NullReferenceException을 던짐.

이제는 ArgumentNullException을 던집니다.

 

5.17 HyperlinkButton이 이제 실버라이트가 들어있는 전체 윈도가 아닌 IFRAME에 대해 내비게이션 동작함.

실버라이트 2에서 HyperlinkButton이 브라우저 사이를 고려하지 않고 동작했습니다. Internet Explorer에서 HyperlinkButton은 현재 IFrame이 아닌 항상 전체 브라우저에 대해 내비게이션하였습니다.

다른 브라우저에서 HyperlinkButton은 오직 현재 IFrame에 대해서만 내비게이션 했습니다. 이 동작이 HTML 특성을 고려한 것입니다. 실버라이트 3에서는 Internet Explorer에서의 동작이 다른 브라우저와 맞도록 변경되었습니다.

 

5.18 실버라이트 2 이상의 애플리케이션이 XAP 파일 확장자를 갖지 않을 때 base URI 문제를 정정함.

실버라이트 2 플러그인에서 .xap 파일의 확장자를 다르게 준다면, 실버라이트는 이 애플리케이션이 실버라이트 1을 위해서 디자인 되었다고 오해하고 실버라이트 1 호환 모드로 동작했습니다. 한 예로 베이스 URI가 .xap 파일이 아닌 HTML page로 인식되었고 다른 예로 기본 폰트가 .xap과 달랐습니다. 이 문제가 수정되었습니다.

 

5.19 Application.Current.Host.Source는 .xap URL이 쿼리 스트링을 포함할지라도 절대 URL을 반환함.

실버라이트 2에서 .xap 파일의 URL이 쿼리스트링을 포함하면 Application.Current.Host.Source가 상대 URL을 반환했습니다. 실버라이트 3에서는 이 문제가 수정되어 Application.Current.Host.Source는 항상 절대 URL을 반환합니다. .xap파일의 URL은 보통 <object>태그 안에서 <param>으로 지정하며 다음은 쿼리 스트링을 포함하는 .xap 파일의 URL 예제입니다.

<param name="source" value="Bin/Debug/bug24857.xap?a=b"/>

 

5.20 ResourceDictionary enum 버그가 수정됨.

실버라이트 2에서 ResourceDictionary에 enum을 넣고 다시 가져오면 enum 타입이 아닌 Integer32 타입의 object를 받았습니다. 이 문제가 실버라이트 3에서 수정되었습니다.

 

5.21 ReadOnlyObservableCollection이 System.Windows.Controls.Data.dll에서 System.Windows.dll로 옮김.

또한 다운로드 크기를 줄이기 위해 잘 사용되지 않는 메서드가 제거되었습니다.

이 수정은 실버라이트 2에서 컴파일된 애플리케이션에는 적용되지 않습니다. 실버라이트 2에서 ReadOnlyObservableCollection를 사용하였다면 .xap 파일에는 System.Windows.Controls.Data.dll이 들어있을 것입니다. 실버라이트 3가 .xap을 실행하면 .xap에 들어있는 System.Windows.Controls.Data.dll 버전의 ReadOnlyObservableCollection을 사용하지 실버라이트 3에서 제공하는 System.Windows.dll 버전을 사용하지 않습니다.

 

5.22 DataGridEndingEditEventArgs가 Silverlight SDK에서 제거됨.

이 EventArgs를 반환하는 곳이 없어서 제거되었습니다. DataGridCellEditEndingEventArgs, DataGridCellEditEndedEventArgs, DataGridRowEditEndingEventArgs, DataGridRowEditEndedEventArgs가 실버라이트 3에 추가되었습니다.

 

5.23 PollingDuplexHttpBinding 변경점.

PollingDuplexHttpBinding이 이제 BasicHttpBinding이 아닌 HttpBinding에서 파생됩니다. PollingDuplexHttpBinding은 이제 SOAP 1.1 대신 1.2 버전을 사용하며, 이로써 실버라이트 3 PollingDuplexHttpBinding은 실버라이트 2버전의 System.ServiceModel.PollingDuplex.dll을 실행하는 ASP.NET 서버와 동작하지 않을 것입니다.

 

5.24 이벤트 핸들러를 제거할 때 버그 수정.

보통 이벤트 수신자를 제거(-= 오퍼레이션)하면, 부분적인 이벤트의 부분적인 딜리게이트만 제거합니다. 실버라이트 2는 이벤트 파트를 무시했습니다. 예를 들어, “object.SomeEvent –= SomeMethod”는 SomeEvent뿐만 아니라 다른 모든 이벤트에서 SomeMethod 메서드에 묶인 모든 이벤트 수신자를 제거했습니다. 이 문제가 실버라이트 3에서 수정되었습니다.

 

5.25 <Cursor>대신 <Cursors>를 허용하는 버그 수정.

실버라이트 2에서는 요컨대 다음과 같은 XAML을 허용했습니다.

<DiscreteObjectKeyFrame.Value>
    <Cursors>Hand</Cursors>  <! -------note plural -->
</DiscreteObjectKeyFrame.Value>

이 코드는 잘못되었습니다. 실버라이트 3는 오직 <Cursor>만 허용합니다.

 

5.26 XAML에서 커스텀 첨부 프로퍼티는 xmlns 접두사를 써야 함.

실버라이트 2에서 다음과 같은 잘못된 XAML을 허용했습니다.

<local:MyControl MyControl.DesignerID="12" />

실버라이트 3에서는 첨부 프로퍼티에 정확하게 XML 접두사를 써줘야 합니다.

<local:MyControl local:MyControl.DesignerID="12" />

 

5.27 서브클래스 컨트롤이 리소스를 잘못 로드할 수 있는 버그 수정.

실버라이트 2에서 클래스 A가 한 사용자 어셈블리에 정의되어 있고 마크업이 다른 사용자 코드 어셈블리안에 있는 클래스 B를 상속하였을 때, Application.LoadComponent(A)가 A의 어셈블리가 아닌 B의 어셈블리에서 XAML을 로드하려고 할 것입니다. 이 문제가 수정되었습니다.(※A어셈블리의 XAML을 로드)

 

5.28 경로에 있는 자식 오브젝트가 null일 경우 ValueConverter가 호출되지 않는 버그 수정.

실버라이트 2 데이터 바인딩은 null에 대해 어떡게 처리할지 고려하지 않았습니다. Path=a.b.c.d로 설정하고 a, b 또는 c가 null이면 실버라이트 2는 ValueConverter를 호출합니다. 그러나 만약 Source=null로 설정하면 이 코드는 ValueConverter를 호출하지 않습니다. 실버라이트 3는 항상 ValueConverter를 호출합니다.

 

5.29 .xap의 바깥 쪽에 있는 리소스를 가리키던 상대 URL가 HTML page가 아닌 .xap 파일에 대해 작용함.

HTML 페이지와 xap 파일이 서로 다른 디렉토리에 있다고 가정해 봅시다. (예를 들어, http://example.com/과 http://contoso.com/ClientBin/) 그리고 xap 파일에 포함되어 있지 않은 상대 URL로 접근하는 리소스가 있다고 합시다. (예를 들어 images/myImage.jpg) 실버라이트 2는 이 URL을 HTML 페이지의 위치에 대해 상대적으로 해석했습니다. (http://contoso.com/images/myImage.jpg) 실버라이트 애플리케이션을 다른 위치로 쉽게 옮길 수 있게 하려고 실버라이트 3는 이 URL을 .xap 파일의 위치에 대해 상대적으로 해석합니다. (http://contoso.com/ClientBin/images/myImages.jpg)

 

5.30 SetBinding() 이후에 Binding 속성을 설정하는 것은 더 이상 지원하지 않음.

실버라이트 2에서 DataContext가 설정되기 전에 SetBinding()이 호출한 경우 이 둘 사이에서 Binding의 프로퍼티를 수정할수 있었습니다.

Binding binding = new Binding();
myElement.SetBinding(HeightProperty, binding);
binding.Foo = value;
myElement.DataContext = …;

각 프로퍼티가 다른 동작을 했습니다.

  • Converter, ConverterParameter, ConverterCulture, NotifyOnValidationError 및 ValidatesOnExceptions 프로퍼티는 SetBinding()으로 초기화된 바인딩에 소급하여 적용됩니다.
  • Mode와 Source 프로퍼티는 무시됩니다.

실버라이트 3는 SetBinding()이 호출된 후에 이 프로퍼티를 변경하면 예외를 던집니다. (실버라이트 2도 DataContext가 설정된 후에 이 프로퍼티를 변경할 경우 비슷하게 예외를 던집니다)

 

5.31 ContentPresenter의 자식은 오직 하나의 부모를 가짐.

실버라이트 2에서 여러가지 이유로 ContentPresenter안의 콘텐트(자식 엘리먼트)가 두 개의 부모를 가질 수 있습니다. 콘텐트가 첫 번째 ContentPresenter에서 제거되지 않은 상태에서 두 번째 ContentPresenter에 추가될 경우입니다. 실버라이트 3는 엘리먼트가 첫 번째 부모에서 제거되지 않은 상태에서 두 번째 부모에 추가되면 예외를 던집니다.

 

5.32 Thumb 컨트롤이 이제는 그 부모에 대해서가 아니라 절대 위치를 기준으로 드래그를 계산.

이 문제는 드래그의 결과로 부모 엘리먼트가 이동할 때 두드러집니다.

 

5.33 DataGrid가 이제는 첫 번째 아이템을 기본으로 선택하지 않음.

 

5.34 DataGrid에서 마지막 아이템이 HorizontalScrollBarVisibility="Auto"일 때 키보드를 사용할 수 없는 버그 수정.

HorizontalScrollBarVisibility가 Auto로 설정되어 있고 수평 스크롤바가 있다면 DataGrid ScrollIntoView API가 마지막 아이템에서 올바로 작동하지 않습니다. 이 경우 마지막 아이템은 수평 스크롤바에 덮힐 것입니다. 다운 키를 눌러 이 API를 사용하여 마지막 아이템까지 내비게이션할 경우에도 같은 동작을 합니다. 워크어라운드는 HorizontalScrollBarVisibility를 Visible로 설정하는 것입니다. 수직 스크롤바는 해당하지 않습니다.

Posted by gongdo
요즘 블로깅 없이 계속 동영상으로 때우는 기분도 들지만...^^;
http://blogs.msdn.com/popcon/archive/2009/07/23/s-5-smooth-streaming.aspx

별거 없지만 참고 슬라이드 :)

다음 시간에는 새로 나온 Expression Encoder 3로 직접 Smooth Streaming 플레이어를 하나 만들어볼까 해요.
기대해 주세요 :D

참고로 실버라이트 하기 좋은 날은 제 블로그 링크만 밝히시면 얼마든지 자료를 다운로드 받거나 퍼가도 돼요.
WMV 동영상 받기

Posted by gongdo

개발자들도 블렌드를 꼭 알아야 한다는 사실!
http://blogs.msdn.com/popcon/archive/2009/07/17/s-4-blend.aspx

[+동영상 다운로드]
Posted by gongdo

좀 늦었지만 3편이 올라왔어요^^
http://blogs.msdn.com/popcon/archive/2009/07/16/s-3.aspx

뭐 4편까지는 아주 기초적인 부분이라 재미도 없고 감동도 없고...
그래도 기초가 있어야 그 다음이 있는거니까요. :)

[+동영상 다운로드]
Posted by gongdo
그 두 번째 시간 :D
http://blogs.msdn.com/popcon/archive/2009/07/09/s-2.aspx

하나씩 설명하자면 끝도 없는 주제지만요, 간단하게 요약하면 아래의 두 이미지로 끝나요. ㅎㅎ


기술적 기반
(참고로 .NET(C#)이라고 쓴 이유는 앞으로 다룰 내용에는 C#을 기준으로 설명한다는 뜻이니 오해 없길 바래요^^;


그래픽 시스템의 핵심

이 개념들만 확실히 이해하면 실버라이트의 다른 모든 기능(feature)을 어렵지 않게 이해하고 확장할 수 있다고 생각해요.

다음 시간은 프로젝트 구성의 기초와 배포 그리고 개발자가 블렌드를 해야 하는 이유...를 설명할 예정인데요,
실버라이트 3도 공개되고 해서 실버라이트 3 특별 방송(?)을 먼저 할지 고민중이에요^^;
그럼 다음 시간에 뵙죠 :D

P.S. 공도의 실버라이트 하기 좋은 날 시리즈는 상업적인 용도만 아니면 링크든 퍼가기든 뭐든 적극 권장합니다. 많이 알려주세요. ㅎㅎ

[+동영상 다운로드]
Posted by gongdo

실버라이트 3가 웹을 통해 정식(RTW)으로 런칭되었어요. 그에 맞춰 See the Light라는 사이트가 열렸는데요, 한 번 들어가보세요^^

http://vepexp.microsoft.com/seethelight

See the Light는 일종의 온라인 컨퍼런스인데요, 작년에 DevDays 2008이 온라인에서 열린 것과 마찬가지 맥락이죠.


 
오프라인 컨퍼런스 분위기로 꾸며놓은 사이트…

 
뭐, 파트너사나 고객, 에이전시 별로 따로 ‘부스’가 마련 되어 있기도 하고요.

전체적으로 오프라인 느낌을 주려고 만들긴 했는데. 뭐랄까 2009년에 이 정도 디자인이라면 뭐어… 딱히 감흥이 있지는 않네요.^^;
그렇지만 키노트나 세션 동영상은 나름 볼만 하니 영어 울렁증을 참고 보는 것도…후우…

그나저나... 아오 이거 볼려고 퇴근도 안하고 있었는데 별 거 없었어 oTL
트위터 낚시주의 ㅠ.ㅜ

+ 보너스
silverlight.net도 실버라이트 3 출시에 맞춰 삼삼하게 변경되었네요.
어차피 메인 페이지가 중요한 사이트는 아니라...(음음)

그 외에도 전반적으로 꽤 파격적으로 변했는데요, 바뀌어서 그런건지 몰라도 썩 편리하지는 않네요.
설치 관련해서는 Microsoft Web Platform Installer란 넘으로 한 방에 설치를 해결한다!...인데 저도 아직 써보진 않았어요 -_-;
MIX09에서 본 Web Platform Installer는 꽤 멋졌던 것 같긴 하지만요.

여튼! See the Light!

Posted by gongdo

드디어 드디어 맑은 고딕 말고도 굴림이나 돋움체를 깔끔하게 볼 수 있어요 ㅠ.ㅜ
백문이 불여일견.

위에서부터 각각 굴림체, 돋움체, 맑은 고딕체로 FontSize="6", 7,8,9,10,11,12,13,14,15,16,20,30 으로 설정한 화면을 캡쳐했어요.

아쉽게도 FontSource 속성은 여전히 설정하고 싶은 모든 Text에 각각 세팅해야 하는 불편이 있지만 혹시 폰트가 없더라도 기본 폰트가 충분한 품질을 뽑아주니 이제 폰트 배포 문제를 덜 고민해도 되겠어요 >_<
우와와와왕ㅋ구우우우우웃ㅋ!!

Posted by gongdo

http://www.sharpgis.net/post/2009/07/09/Silverlight-3-Released.aspx 여기에 잘 포스팅 되어 있고, 저도 해봤어요.

1. MouseWheel이 드디어 지원되네요 :D
중요한 사실을 빼먹었네요. 이 MouseWheel 이벤트는 FullScreen에서도 지원된다는 사실! 우오오오옷!

2. 구동 환경이 Windows 7일 경우 멀티터치를 지원!! 우오오오옷!!!!!
근데 난 터치디바이스가 없을 뿐이고 ㅠ.ㅜ

3. 8bit 투명 PNG 지원. 아쉽게도 1,2,4bit는 지원 안한다는군요. ㅠ.ㅜ

4. Out-of-browser 기능을 프로젝트 속성에서 GUI로 조절 가능.

5. 기본 Behavior가 제공됨.
진짜 뭘 하든 꼭 필요한 것들만 모아둔 것 같아요!

사소한거지만 메인 페이지의 XAML에서 기본 배경색상이 투명으로 바뀌었고 블렌드를 위한 xmlns가 기본으로 정의 되었네요.

우와왕ㅋ굳ㅋ!!! 으아아아아 빨리 쓰고 싶다 >_<

Posted by gongdo

드디어 나왔어요! 아직 공식 사이트인 silverlight.net에는 올라오지 않았지만 마이크로소프트 이반젤리스트 블로그를 중심으로 링크가 공개되었네요. 사족이지만 RTW란 Release To Web의 약자로 정식 버전이 맞아요^^
설치는 전과 마찬가지로 기존에 설치된 모든 실버라이트 관련 설치를 제거하고 다음 링크에서 새로 설치하면 돼요.

[개발자 필수]

[디자이너 필수 + 개발자도 어지간하면 설치]

[End-user용 실버라이트 3]

참고로 Blend 3 with SketchFlow는 일종의 RC버전으로 Final은 2주 정도 후에 나온다고 '유력한' 소식통이 전해왔어요.
자세한 리뷰는 나중에 하기로 하고 인증샷들만….

 

RTW 버전은 3.0.40624.0 즉, 6월 24일에 이미 최종 버전의 빌드가 되었다는 것을 알 수 있죠.

 

 

블렌드 3 설치 화면. 와~우 깔끔해졌어요~

 

 

블렌드 3 + 스케치플로우! 근데 저기서 춤 추는지 뭐 하는지 포즈 잡는 사람들은 뭔가…=_=

블렌드 3의 새 아이콘. 음… 판단 유보.

 

새 프로젝트 만들기. 좀 더 많은 종류의 프로젝트를 지원하면서 창도 늘어났네요. 당연한 얘기지만 실버라이트 2는 지원하지 않아요.

 

변경된 블렌드 3의 화면. Asset을 좀 더 빠르게 접근할 수 있도록 구성했군요. 그런데 모니터 해상도가 높아야 좋을 것 같네요. 해상도 작으면 오밀조밀해서 답답할 듯. 노트북 유저들 안습 ㅠ.ㅜ

 

드디어 공개된 스케치 플로우!! 우와아아앙 빨리 써보고 싶다아아아아 >_<

Posted by gongdo

제가 또 일 끝까지 안하고 새로 일 벌리는 걸 좋아하죠. (…후우…)

MSDN POPCON에 ‘공도의 실버라이트 하기 좋은 날’이란 동영상 시리즈를 연재하기로 했어요. 매주 목요일날 업데이트 예정이고요, 내용은 그야말로 자유. 피드백 많이 주세요 :D

그 대망의 시리즈 제 1편: http://blogs.msdn.com/popcon/archive/2009/07/02/s-1.aspx

소개가 참 간드러지게 나왔는데요, 제가 원래 그 모양이니 모…ㅎㅎ

아래는 기각당한 초안이에요. 사실 이쪽이 더 마음에 들어서 남겨놉니다.^^

한 몇 개월 전부터 실버라이튼지 뭔지 하는 게 자꾸 사람들이 얘기는 하는데,
그까이꺼 대애애~충 훑어보니 뭐 별 어려워 보이는 것도 없고 해서 한 번 해 보는데,
팀장님이 '너 뭐하냐?' 물어보니 나름 깝쭉대 보지만?
아뿔사! 이건 뭐 내가 뭘 하는 지 설명을 못하겠네...
하는 당신을 위한 초고농도압축액기스추출 동영상!
액기스만 모았습니다. 짧습니다. 효과 (아마도)확실합니다!
(※부작용 발생 시 가까운 개발자나 디자이너에게 하소연하시기 바랍니다.)

P.S. 
손발은 오글오글.

[+ 동영상 다운로드]

Posted by gongdo

※스위치를 잘못 썼네요. -(대시)가 아니라 /(슬래시)에요;

흔히 마이크로소프트에서 배포하는 설치파일은 무인설치(Unattended installation) 라고 해서 설치 화면을 보여주지 않고 설치할 수 있는 옵션을 제공하죠.

실버라이트 설치 파일도 마찬가지에요. 방법은 아주 심플. 커맨드 프롬프트에서 실버라이트 설치 파일이 있는 디렉터리로 이동한 후 다음 커맨드를 입력하면 돼요.

  • 설치
    Silverlight.3.0.exe /q
  • 제거
    Silverlight.3.0.exe /qu

참 쉽죠? :p

참고로 당연하겠지만 윈도 비스타 이상에서는 삭제나 설치할 때 UAC가 뜨게 되죠.

어디다 쓰냐고요? 물론 웹으로만 배포할 경우에는 별로 쓸모 없겠지만 엔터프라이즈 솔루션의 경우 실버라이트 애플리케이션이 솔루션의 일부로 포함될 수도 있겠죠. 이럴 때 한꺼번에 배포한다면 편리할 거에요.

Posted by gongdo
I posted how to use DataBinding with Behaviors in Silverlight 3 recently. However, it turns out, it's impossible or very limitted.

Follow code is what I expected to work.

<Grid x:Name="LayoutRoot" Background="White">
    <Button Content="Test" HorizontalAlignment="Right">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Click">
                <hi:ShowMessageBoxAction x:Name="Action1"/>
            </i:EventTrigger>
        </i:Interaction.Triggers

        <i:Interaction.Behaviors>
            <hi:BindingProxyBehavior
                        TargetName="Action1"
                        TargetPropertyName="Message"
                        Binding="{Binding Path=MockString}" />
        </i:Interaction.Behaviors>
    </Button>
</Grid>

[It doesn't work, 'cause Behaviors are not FrameworkElements]

- ShowMessageBoxAction which named "Action1" by x:Name attribute has a property named Message.
- BindingProxyBehavior is a Behavior. And it figures out "Action1" by AssociatedObject(LayoutRoot).FindName method when it has been invoked.

But It's impossible, 'cause Behaviors are not Frameworks so they can't be found by FrameworkElement.FindName method.

It's OK, I can understand why is it impossible. However how do you think about code follow:

<DataTemplate x:Key="DataTemplate1">
    <Grid>
        <Button HorizontalAlignment="Left" Content="{Binding Mode=OneWay, Path=Title}">
            <i:Interaction.Triggers>
                <i:EventTrigger x:Name="Trriger1" EventName="Click">
                    <hi:ShowMessageBoxAction x:Name="ShowMessageAction"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>           

            <i:Interaction.Behaviors>
                <hi:BindingProxyBehavior
                    TargetName="ShowMessageAction"
                    TargetPropertyName="Message"
                    Binding="{Binding Path=Description}" />
            </i:Interaction.Behaviors>
        </Button>
    </Grid>
</DataTemplate>

[Does it work or not?]

It's similar to first one, except root Grid is in the DataTemplate.
Guess what? it works. Very well.
HOW COME!? Isn't it wierd?

Now I have to give up to do DataBinding with Behaviors in Silverlight 3 by that way.
It makes me depressed. "No binding, more work".
Anyway all I really want to ask Microsoft is, just allow us DataBinding with Behaviors, so we can create application rapidly, design-friendly, and even elegantly! Like follow code:

<Grid x:Name="LayoutRoot">
    <Button Content="Test">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Click">
                <hi:ShowMessageBoxAction
                    x:Name="Action1"
                    Message="{Binding Path=Description}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </Button>
</Grid>

[Elegant DataBinding with Behaviors]

Here for sample project:

Posted by gongdo
Because Behaviors are not FrameworkElements, you can't use DataBinding with Behaviors. I posted this about it before.

<Button Content="Description">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
            <local:ShowMessageBoxAction Message="{Binding Description}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</
Button>
[You can't use DataBinding with Behaviors like above]

Well, I'm still thinking about that it's the best way to use DataBinding with Behaviors. Why I can't do like that! However, if you really want to mix up DataBinding and Behaviors just like me, there are some work-arounds.

First, you can attach a 'Binder' class to FrameworkElement as an AttachedProperty. Morten Nielsen writed such a cool class, 'SurrogateBinder' which is general data binding helper. It could be attached to any FrameworkElement, and it passes through the value which from data source to actual target. Here's sample code:

<TextBox RenderTransformOrigin="0.5,0.5"
        Text="Hello Universe!"
        binders:SurrogateBind.Value="{Binding Path=MoreValues.Heading}" 
        binders:SurrogateBind.Target="RenderTransform.Children.Item[1].Angle" >
    <TextBox.RenderTransform>
        <TransformGroup>
            <ScaleTransform />
            <RotateTransform />
        </TransformGroup>
    </TextBox.RenderTransform>
</TextBox>

It works well with any property of FrameworkElement but not for AttachedProperty like Behaviors. So you must modify little bit to targeting AttachedProperty. Also SurrogateBinder can't be set on Blend, so most of designers might not want to use it. Blend-support is important for XAML design. So I don't prefer in-line AttachedProperty as a solution, even though it is cool & smart.

SecondPete Blois who is a program manager of Expression Blend introduced this article to show how Binding property could be used with Blend for binding to non-FrameworkElement, like Behaviors. As you know, we can't use DataBinding to properties on Behaviors, 'cause Behavior is not a FrameworkElement. But Blend seems to allow DataBinding to a property which is type of Binding. Hey! it's so tricky isn't it? :(

<i:Interaction.Behaviors>
    <id:DataStateBehavior Binding='{Binding IsOnline}' Value='True'/>
</i:Interaction.Behaviors>
[You can use DataBinding only on a property which is type of Binding. Could you guess that?]

It looks much cooler than other, but it's not a general solution. Imagine that you want to bind to 3rd party's Behavior, you nerver can do, of course it might has no Binding property! However, sample is just sample and actually it's not only for DataBinding with Behavior but also for Trigger which is raised by condition of data.

Thrid. Now, here's my approach.

<i:Interaction.Triggers>
    <i:EventTrigger EventName="Click">
        <hi:ShowMessageBoxAction x:Name="ShowMessageAction"/>
    </i:EventTrigger>
</i:Interaction.Triggers>
<i:Interaction.Behaviors>
    <hi:BindingProxyBehavior
        TargetName="ShowMessageAction"
        TargetPropertyName="Message"
        Binding="{Binding Path=Description}" />
</i:Interaction.Behaviors>


Sigh, looks messy huh? But it based on standard Behavior, so it works well with Blend and you don't need to worry about writing these XAML code. Blend will generate XAML code as well as you write.
'BindingProxyBehavior' implements Behavior class, and it exposes  some properties which are needed to determine DataBinding & binding target. It focuses only one binding per an instance, but you can attach multiple instance of it, 'cause it's a standard Behavior.

Here's sample project. Enjoy it :)


Actually I'dont like any of them, but first code-block which is impossible currently. So I really want to say, why not with DataBinding? Please?
Posted by gongdo
뭐 결론부터 말하자면 VS2010에서 실버라이트 프로젝트를 테스트 할 수 있다 외에 특별히 장점이 없네요.

우선 VS2010에서는 아직 실버라이트 툴링 부분에는 집중하고 있지 않나봐요.
가장 타격이 컸던건 XAML에서 인텔리센스가 뜨긴하는데 Enum값은 안나오는 등 여러모로 신경을 거슬리게 하는게 있어요.
그래서 저도 걍 깔아봤다에 의의를 두고 메인 작업은 VS2008 + 실버라이트 3 베타 1으로 하려고요.


스샷으로는 잘 안보이겠지만 VS2008 + Silverlight 2, VS2010 + Silverlight 2, VS2010 + Silverlight 3환경에서 동시에 개발할 수 있어요. 참고로 현재 OS는 Windows 7 빌드 7127 x64 환경인데요, 문제 없이 잘 되네요. :D

(윈도 타이틀 바가 투명으로 나와서 간지나죠? 이건 Windows 7 빌드 7127에서 가능한 레지스트리 조작인데요, 스누피님의 블로그를 참고^^ http://snoopy.textcube.com/775)

여튼 설치 순서는 아래에. 중간에 선택 사항도 있으니 잘 보시길.

1. 마음을 비우고 윈도 재설치(생략 가능)
2. Visual Studio 2008 설치
3. TeamExplorer 2008 설치(옵션)
4. Visual Studio 2008 SP1 설치
5. Visual Studio 2010 beta 1 설치

(VS2008에서 실버라이트 2 개발환경으로 할 경우)
6-1. Silverlight 2 Tools for Visual Studio 2008 SP1 설치
6-2. Silverlight 3.0 beta 1 SDK 설치
6-3. Silverlight 3.0 beta 1 개발자 런타임 설치
6-4. Expression Blend 3 preview 설치
6-5. Expression Blend 2 설치
6-6. Expression Blend 2 SP1 설치

(VS2008에서 실버라이트 3 개발환경으로 할 경우)
6-1. Silverlight 2.0 SDK 설치
6-2. Silverlight 3 beta Tools for Visual Studio 2008 SP1 설치
6-3. Expression Blend 2 설치
6-4. Expression Blend 2 SP1 설치
6-5. Expression Blend 3 preview 설치

7. 기타 등등.

주욱 늘여놓으니까 복잡해보이지만 막상 해보면 당연히 그렇게 해야 할 것 들이라서요.
아마 VS2010씩이나 테스트 하시는 분들이라면 자세한 설명은 없어도 될 것 같아서 생략합니다.
Posted by gongdo
지난 16일, Dev&Tech Festival 2009 행사의 일환으로 훈스닷넷에서도 커뮤니티 세미나를 가졌어요. 비가 오는데도 자리를 꽉 채울 만큼 많이 오셔서 감사합니다.^^

이번에는 디자이너 이은아님과 함께 실버라이트 3 가지고 놀기라는 주제로 준비를 했어요.


실버라이트 3는 아직 베타 상태로 나온지 얼마되지 않았기 떄문에 실버라이트에 익숙하지 않으신 분들을 위해서 최대한 재밌는 데모 위주로 진행하려고 노력했는데 끝나고 올라온 후기를 보니 XAML(재믈)이 무슨 말인지 몰라서 이해하기 어려웠다는 분들도 계셨어요. 좀 더 설명을 덧붙였어야 했구나 하는 생각도 들어요.

여튼 발표한 내용은 크게 픽셀 이펙트와 비헤이비어에 촛점을 맞춰서 어떤 식으로 활용되는지 소개를 했고요, 시간 관계상 소개를 하지는 않았지만 데모 전반에 네비게이션 프레임을 적극적으로 활용하여 페이지 구성과 전환을 디자이너가 직접 할 수 있게 해봤어요. 

데모는 간단해보이지만 나름 공을 많이 들인 야근기담(^^)이 준비하면서도 즐거웠고 실버라이트 3가 등장하면서 달라질 디자인-개발 프로세스에 기대를 갖게 만들었어요. 다시 보면서 손발이 오그라들긴 하지만 제가 직접(!) 출연한 기타 히어로 공연(-_-)은 세미나 당일날 급조한거죠. 사실은 이걸 위해 무려 의상도 직접 준비한건데요, 원래는 라이브로 하려던 거였는데 준비가 미흡해서 제대로 쇼를 못한건 아쉬워요. 허허헛...

마지막으로 날리는 썩소 씨-익 ^_____,^


Posted by gongdo
DTFE2009 - Dev&Tech Festival 행사의 일환으로 훈스닷넷이 UX 세미나를 하죠.
저도 은아님과 함께 1세션 - 실버라이트 3 가지고 놀기를 주제로 발표를 해요.

하루 밤 날 새서 만든 예고 편... 참고로 실버라이트 3 런타임이 설치되어 있어야 해요. [런타임 다운로드]
실버라이트 2 개발 환경에서도 런타임만 따로 설치해도 되니깐 한 번 해보세요^^
+ 볼륨 업!!


세미나에서 만나요 :D

Posted by gongdo

The Binding object only can take DependencyProperty on the FrameworkElement as a binding target in Silverlight. ‘Course, all of methods and properties related to DataBinding is on the FrameworkElement. DataBinding model might be designed to bind a source data to target ‘UI Element’ at the first time, I guess. It’s reasonable, and it looks like flawless. Just Before Behaviors feature was added to Silverlight.

Oneday, I created a simple Silverlight 3 application to explain Behaviors for my coworkers with Silverlight 3. Me and my coworkers were quite familiar with DataBinding through expierence of Silverlight 2, so I wanted to show them a demo with DataBinding.

The behavior what I created was very simple, you might already know ‘ShowMessageBoxAction’ if you tried Silverlight 3 Behaviors. Here’s the code:

 public class ShowMessageBoxAction : TriggerAction<DependencyObject>
{
    public string Message { get; set; }

    protected override void Invoke(object parameter)
    {
        MessageBox.Show(Message);
    }
}

Yes it was a triggered action which shows MessageBox when Click event raised on Button. Nothing special, isn’t it? And then I wanted to mix it up DataBinding like:

<Button Content="Description">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
            <local:ShowMessageBoxAction Message="{Binding Description}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</
Button>

If you are a developer who is familiar with DatatBinding, you might be aware of my mistake and it would never work. As I mentioned above, a target of DataBinding must be a DependencyProperty on FrameworkElement. I think I got out of my mind at that time. It’s absolutely my mistake because all the Triggers and Behaviors were not FrameworkElement so these were not parts of VisualTree.

However, was that approach bad or evil? Well, I don’t think so. Because it looks like natural. I mean, when we write some XAML codes, It’s not easy to be aware of whether an element(tag) is a FrameworkElement or just other AttachedProperty. And it’s almost impossible to explain it reasonably for designers. Imagine that how designers add some behaviors to an element by using Expression Blend, Behaviors will shown on ‘Object Tree Panel’, not a just Property Panel. Who could know it’s impossible to use DataBinding untill opened a property panel of a Behavior and realize that DataBinding property was disabled.

What do I want to say? Well, I’m understand why Behaviors can’t be binded using DataBinding. However I think DataBinding makes work easy and efficeint, so how about if DataBinding could reach through any DependencyObject or AttachedProperty element?


Posted by gongdo

Because, Silverlight 2 also can reference to Microsoft.Expression.Interactivity Assembly which is from Blend 3 library, you can take many advantages of Behaviors model from Silverlight 3 in Silverlight 2 as well. Yes, you can write Behaviors code without version dependency, and it can be referenced by both of Silverlight 2 and 3.

When I found that possibility, I was excited. As you know, Behaviors model brings you a great functionality which might reduce ‘bording-coding’ dramatically. All you have to do is that just copy-paste XAML from Blend 3, absolutely better than Blend 2, And even no code-behind!

I'm going to show you how to make a simple Silverlight 2 application using a simple trigger-action behavior. Create a new Silverlight project, and follow next steps.

Step 1. Referece a Microsoft.Expression.Interactivity Assembly.

Simply, copy a Microsoft.Expression.Interactivity Assembly to any folder to reference from your application. Usually, you can find it C:\Program Files\Microsoft Expression\Blend 3 Preview\Libraries\Silverlight folder if you installed Blend 3 Preview.

Notice that you must rename the assembly file, because Blend 2 can’t recongnize the name contains ‘Microsoft.Expression’. I don’t know why Blend 2 blocks specific assembly names like that. So just rename it say, Interactivy.dll or something. In this example, I renamed Microsoft.Expression.Interactivity.dll to Interactivity.dll. 

After you reference the assembly, you might be encountered an error follow:

It makes you blind in Visual Studio. Don’t panic. :) It’s  just a bug in Visual Studio Designer which already known. However Blend 2 will display it fine, if there was no other errors. Check this out further information.

Step 2. Create a simple trigger-action behavior.

Now, add a class say, ShowMessageBoxAction. It’ll show message box when trigger event raised on associated object.

public class ShowMessageBoxAction : TriggerAction< Dependencyobject>
{
    #region Message

    ///  
    /// Gets or sets the Message possible Value of the string object.
    ///  
    public string Message
    {
        get { return (string)GetValue(MessageProperty); }
        set { SetValue(MessageProperty, value); }
    }

    ///  
    /// Identifies the Message dependency property.
    ///  
    public static readonly DependencyProperty MessageProperty =
    DependencyProperty.Register(
        "Message",
        typeof(string),
        typeof(ShowMessageBoxAction),
        new PropertyMetadata("Message")
    );

    #endregion Message

    protected override void Invoke(object parameter)
    {
        MessageBox.Show(Message);
    }
}

It has a property which you want to show up, and it ovverides Invoke method which is called when trigger event raised.

Step 3. Add a button with trigger.

Make some UI to check trigger performs well, follow:

<UserControl
    x:Class="SL2Behaviors.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:i="clr-namespace:Microsoft.Expression.Interactivity;assembly=Microsoft.Expression.Interactivity"
    xmlns:local="clr-namespace:SL2Behaviors"
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <Button Content="Click Me">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                    <local:ShowMessageBoxAction Message="Hello Behaviors in Silverlight 2!" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>
    </Grid>
</UserControl>

Step 4. Build & run!

How is it? It works fine like Silverlight 3 does. Also you can use other Behaviors like this as well. Try it after these steps. Yes, now you can use Behaviors in your Silverlight 2 applications.

Here is source code for above. It'll be more helpful rather than my poor English. :)



Posted by gongdo

제 메인 PC의 개발 환경이 실버라이트 2로 되어 있어서 자료 정리에 시간이 많이 걸렸네요. 여튼 4월 18일 건국대 새천년 기념관에서 개최된 제 1회 DevDcc 행사에서 발표했던 “실버라이트 3의 등장과 디자인-개발 패러다임의 변화”의 PPT와 데모에요.

데모1에서는 디자이너 이은아님과 함께 처음 실버라이트를 접한 디자이너와 어느 정도 실버라이트 개발에 익숙해진 개발자가 겪을 수 있는 문제점을 다뤄봤어요. 디자이너와 개발자가 서로의 작업을 이해하고 도와주는 것이 역시 유일한 답이겠죠. 또 데모에는 남성 개발자들의 압도적인 지지를 받고 있는 *소녀시대*의 gee 영상으로 카드를 만들어 봤는데요, 아마 데모보다 이쪽에 더 관심 있는 분들이 많지 않을까 하네요 ㅎㅎ.

또한 데모1에서 자세한 설명은 하지 않았지만 Perspective 3D와 데이터 바인딩 그리고 WrapPanel등 실버라이트 3에서 새로 추가되거나 강화된 기능들을 적극적으로 활용하여 만들었으니 어느 정도 참고가 될 거에요.

데모 2에서는 디자이너 장미연님과 함께 했는데요, 장미연님은 현업에서 WPF 프로젝트를 수행하고 있고 개발과 디자인의 중간영역에서 디자이너가 어떤 역할을 해야 하는지에 대해 많은 경험을 가지고 계시죠. 또한 프로젝트 특성상 데이터를 다루는 일이 많은데요, 이 데모를 통해 실버라이트 3 그리고 블렌드 3에서 강화된 데이터 관련 기능을 어떻게 활용하는지 제시하고 있어요.

데모 2에서 개발자는 데이터 원본 생성과 패널 및 컨트롤 코드를 작성하는 임무를 맡고 디자이너는 그 데이터와 컨트롤들을 활용하여 자유롭게 디자인 할 수 있죠. 데모에서 최종적으로는 기존의 딱딱했던 사각형의 리스트박스에서 벗어나 애니메이션 효과와 함께 원형으로 배치되는 패널을 사용하여 데이터를 표시하고 있어요.

데모 3에서는 디자이너 김선구님과 함께 실버라이트 3에서 추가된 가장 강력한 기능 중 하나인 비헤이비어Behaviors에 대해 알아봤는데요, Behaviors는 크게 트리거Trigger & 액션Action과 비헤이비어Behavior로 나눌 수 있어요. Trigger&Action은 어떤 오브젝트에서 이벤트가 발생했을 때 특정 동작을 수행하는 것을 말하고 Behavior는 어떤 오브젝트가 가지는 그 외의 모든 행동 특성을 의미해요. Behaviors는 개발자에게 오브젝트의 행동을 모듈 단위로 설계하도록 도와주고 디자이너에게는 이 Behaviors를 사용하여 개발자의 도움 없이도 멋진 인터랙션을 가지는 애플리케이션을 디자인 할 수 있어요.

데모 3에서는 Behaviors의 활용을 극대화 하여 심지어 물리엔진 조차도 아주 간단하게 사용할 수 있는 방법을 제시하는데요, 저는 Behaviors의 개념이 앞으로 애플리케이션의 개발 패러다임을 확 바꿀 수 있다고 확신해요.

발표 자료가 이미지 중심으로 이루어져 있어서 자세한 설명은 동영상으로 보는 게 좋을 텐데요, 아쉽게도 아직 동영상 자료의 인코딩과 편집이 덜 끝났어요. 동영상이 업데이트 되면 블로그에 업데이트 할게요.

다시 한번 DevDcc 행사에 참가해주신 여러분께 감사 드립니다. ^^/

Posted by gongdo
아오 맨날 하는 소리지만 정말 힘들었네요. 힘들었지만 나름 회사 일도 개인적인 일도 같이 해내서 뿌듯해요.
행사 끝내고 원고 하나 쓰고 16시간 자다가 지금은 회사일 하는 중 ㅋ

발표 자료는 내일 정도에 모아서 올릴 생각이에요. 소시 동영상 때문에 용량이 후덜덜 하네요. 줄여서 올려야겠어요. 핫핫...

Posted by gongdo
간 마이크로소프트웨어 4월호에 기고한 내용이에요. 데이터 바인딩의 기초적인 원리와 어떻게 사용하는지에 대한 설명 및 소스가 있어요.
--------------------------

지난 글에서 실버라이트로 데이터 바인딩을 살짝 맛보았다이번에는실버라이트의 데이터 바인딩이 구체적으로 어떻게 이루어졌는지그리고 어떤 기능들을 제공하는지 알아보겠다

데이터 바인딩의 동작 원리 

데이터 바인딩은 기본적으로 UI 엘리먼트와 데이터를 연결하는 것을말한다이를 구현하는 것이 바로 Binding 클래스이고, ystem.Windows.Data 네임스페이스에서 찾을 수 있다지난글에서 우리가 사용했던 Text=”{Binding Path=Name}” 과 같은 바인딩 표현식에서도 Binding 지시자를 통해 UI 엘리먼트와 데이터가 연결되는 것을하였다이들 사이의 관계를 도식화 해보자면 다음과 같다.


[그림 1. 데이터 바인딩의 구조]

l  바인딩 엔진, Binding 클래스는 바인딩 원본과 바인딩 대상의 사이에서 서로의 값을 설정하거나 변화를 감시하는 역할을 수행한다.

l  바인딩 원본은 어떤 종류의 CLR 개체도 사용할 수 있으며 바인딩 원본의 바인딩 할 속성도 제한이 없다.

l  바인딩 대상은 반드시 FrameworkElement에서 파생된 클래스이어야 하고 바인딩 대상 속성은 반드시 DependencyProperty이어야 한다.

l  화살표는 바인딩의 방향을 나타내며 구성에 따라 단방향 혹은 양방향으로 연결할 수 있다.

l  바인딩에 의해 값이 변경될 때 ValueConverter가 지정되어 있을 경우 값이 적절하게 변환되어 설정된다.

 

바인딩은 다른 실버라이트 개체들과 마찬가지로 XAML과 코드로 선언할 수 있다.

[XAML]
<TextBlock Text="{Binding Id}" />

[C#]
TextBlock tb = new TextBlock();
Binding binding = new Binding("Id");
tb.SetBinding(TextBlock.TextProperty, binding);

 [리스트 1. 데이터의 Id속성을 UI Text속성에 바인딩하는 코드 조각]

이렇게 Binding 개체에 의해 연결된 바인딩은 명시적으로 데이터 바인딩 할 원본 개체의 인스턴스를 설정하지 않으면 기본적으로 DataContext 속성에 설정되어 있는 데이터 개체로부터 바인딩 할 원본 속성을 찾는다. DataContext는 실버라이트의 비주얼 트리를 타고 하위 개체로 전파되므로 공통적인 데이터 바인딩을 하는 UI 집합에서 편리하게 사용할 수 있다.


[그림 2. DataContext를 이용한 바인딩 원본 개체 설정]

바인딩의 기능과 표현식

 바인딩은 단순히 데이터와 UI 엘리먼트를 연결하는 기능 외에도 다양한 바인딩 시나리오를 위한 기능이 준비되어 있다. 각각의 기능과 표현식에 대해 알아보자. 아래에 소개한 기능과 표현식의 모든 소스 코드는 [DataBindingFeatures]의 각 폴더에서 찾아 볼 수 있다.

1.      바인딩 할 원본 개체의 속성 설정

앞서 소개한 것처럼 바인딩 할 원본 개체의 속성은 Binding 클래스의 Path 속성을 사용하여 지정한다. XAML에서 바인딩 표현식을 사용할 때에는 Path지시자를 생략하고 바인딩 할 원본 개체의 속성만 지정할 수 있다

또한 Path 속성을 아예 생략할 수도 있는데, 이 경우 바인딩 대상 속성에는 바인딩 원본 개체 그 자체가 바인딩 된다.

[XAML]
<TextBlock Text="{Binding Path=Name}" />
<!-- 또는 -->
<TextBlock Text="{Binding Name }" />
<!-- 또는 -->
<TextBlock Text="{Binding }" />

[리스트 2. 바인딩 경로를 설정하는 XAML 표현식]

2.      명시적인 데이터 원본 설정

데이터 원본은 Binding클래스의 Source 속성으로 설정할 수 있다. Source 속성을 생략할 경우 자동으로 DataContext에서 바인딩할 속성을 가져온다. 일반적인 경우 Source 속성을 생략하고 DataContext로부터 바인딩 받는 경우가 대부분이지만 때로 명시적인 DataContext가 아닌 명시적인 원본 설정이 필요할 때도 있다.

[XAML]
<TextBlock Text="{Binding Path=Id, Source={StaticResource MyProfile} }" />

[리스트 3. 명시적으로 바인딩 원본을 설정하는 XAML 표현식]

XAML에서 Source를 명시적으로 사용하기 위해서는 먼저 해당 엘리먼트를 포함하는 사용자 컨트롤이나 App.xaml에 반드시 바인딩할 원본을 리소스로 등록한 후 StaticResource 표현식을 사용하여 설정해야 한다. 위의 예제는 리소스로 등록된 MyResource 개체를 바인딩 원본으로 사용하여 MyResource.Id 속성을 Text 속성에 바인딩한다는 의미이다.

3.      데이터의 흐름 설정

Binding 클래스의 Mode 속성으로 원본을 대상에 어떤 방향으로 바인딩 할지 설정할 수 있다. 데이터 흐름에는 다음과 같은 세 종류가 있으며 Mode 속성이 생략 될 경우 자동으로 OneWay 방식이 선택된다.

l  OneTime
최초로 바인딩 원본이 설정될 때 단 한번만 바인딩 대상을 변경하는 모드.

l  OneWay
바인딩된 원본이 변경사항을 알려줄 때마다 자동으로 바인딩 대상도 변경하는 모드.

l  TwoWay
바인딩 대상이 변경되었을 때 역으로 바인딩 원본도 변경하는 양방향 모드.

[XAML]
<TextBlock Text="{Binding Id, Mode=OneTime}" />
<!-- 또는 -->
<TextBlock Text="{Binding Id, Mode=OneWay}" />
<!-- 또는 -->
<TextBlock Text="{Binding Id, Mode=TwoWay}" />

[리스트 4. 바인딩 흐름을 설정하는 XAML 표현식

, OneWay TwoWay 모드가 정상적으로 동작하기 위해서는 데이터 원본 오브젝트가 반드시 다음의 INotifyPropertyChanged 인터페이스를 구현해야 한다.

4.      데이터 원본의 변경 알림

위에서 본 데이터 바인딩의 OneWay혹은 TwoWay 모드는 데이터 원본이 변경되면 자동으로 바인딩 대상도 변경되어야 한다. 이를 위해 데이터 원본 개체는 자신의 데이터가 변경될 때 바인딩 개체에 그 사실을 알려줘야 한다.

이 과정은 모든 CLR 개체에서 자동으로 되는 것이 아니라 INotifyPropertyChanged라는 인터페이스를 상속받은 개체에서 코드를 통해 명시적으로 구현을 해야 한다.

[C#]
public class Profile : INotifyPropertyChanged
{
    private string _id;
    public string Id
    {
        get { return _id; }
        set
        {
            _id = value;
            FirePropertyChanged("Id");
        }
    }
    #region INotifyPropertyChanged Members
    public event PropertyChangedEventHandler PropertyChanged;
    protected void FirePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion
}

[리스트 5. INotifyPropertyChanged 인터페이스를 구현하는 원본 개체의 예제

이렇게 데이터 원본은 PropertyChanged 이벤트를 발생시키고 바인딩 엔진은 그 이벤트를 받아 바인딩 대상 속성을 변경한다.

5.      데이터 컨버팅

때로는 바인딩 원본 속성의 타입과 바인딩 대상 속성의 타입이 일치하지 않을 수도 있다. 예를 들어 TextBlock Text 속성에 DateTime 타입의 값을 바인딩한다면 시스템의 로캘에 따라 “18/03/2009 PM 08:09:00”과 같이 원치 않는 형식으로 바인딩되는 것을 볼 수 있다. 이 때 IValueConverter 인터페이스를 상속하는 클래스를 하나 만들고 IValueConverter 인터페이스의 Convert 메서드와 ConvertBack 메서드를 구현하면 된다. 이렇게 구현한 ValueConverter는 먼저 XAML에 리소스로 등록을 한 후 Binding 클래스의 Converter속성에 리소스를 설정하면 된다. 또한 ConverterParameter 속성을 사용하면 값을 변환할 때 옵션을 부여할 수 있다.

[XAML]
<TextBox Text="{Binding Birthday,
                 Mode=TwoWay,
                 Converter={StaticResource DateConverter},
                 ConverterParameter=yyyy MM dd}" />
 [C#]
public class DateValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // 생략
        return ;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // 생략
        return ;
    }
    #endregion
}

[리스트 6. IValueConverter 인터페이스를 구현하는 원본 개체의 예제

Convert 메서드는 데이터 원본에서 바인딩 대상 방향으로 설정할 때 사용되고 ConvertBack 메서드는 반대로 바인딩 대상의 변화를 데이터 원본에 설정할 때 사용된다. 참고로 앞의 코드 조각에서 볼 수 있듯이 바인딩 표현식은 보기 좋게 정리하기 위해 표현식의 각 지시자 사이에 엔터를 포함한 공백을 넣을 수 있다.

6.      데이터 유효성 검사

TwoWay 바인딩이 설정된 TextBox에서 사용자가 문자열을 입력하면 입력된 문자열이 다시 데이터 원본 속성에 설정이 된다. 이 때 기본적으로 데이터 원본 속성의 설정자에서 사용자 입력의 유효성을 검사할 수도 있고 ValueConverter를 사용하여 유효한 형태로 변환할 수도 있다. 그러나 이렇게 할 경우 사용자가 잘못된 입력을 했다는 것을 상위 UI에 알려주려면 별도의 이벤트나 메서드를 사용해야 한다. 특히 복잡한 UI를 가진 입력 폼 등의 애플리케이션은 표준적인 입력 오류를 알려주는 수단이 필요하다.

Binding 클래스는 데이터 유효성 검사를 위해 ValidatesOnExceptions 속성과 NotifyOnValidationError 속성을 지원한다. 이 두 속성을 모두 True로 설정하면 데이터 원본의 속성이 바인딩 엔진에 의해 설정 중에 발생된 예외를 잡아서 BindingValidationError 이벤트로 전달한다. BindingValidationError 이벤트는 모든 FrameworkElement가 가지고 있는 이벤트로 이벤트가 발생한 엘리먼트에서부터 시작하여 이벤트가 처리될때까지 상위 엘리먼트로 계속 라우팅되는 버블 이벤트이다.

[XAML]
<TextBox
    Text="{Binding Path=Age,
    NotifyOnValidationError=true,
    ValidatesOnExceptions=true}" />
[C#]
public class Profile : INotifyPropertyChanged
{
    private int _age;
    public int Age
    {
        get { return _age; }
        set
        {
            if (value < 0 || value > 150)
                throw new Exception("나이는 0~150까지만 가능합니다.");
            _age = value;
            FirePropertyChanged("Age");
        }
    }
}
// 바인딩 에러 처리
void Page_BindingValidationError(object sender, ValidationErrorEventArgs e)
{
    // 에러가 발생할 때 처리
    if (e.Action == ValidationErrorEventAction.Added)
        ErrorCaption.Text = e.Error.Exception.Message;
    // 에러가 해결되었을 때 처리
    else if (e.Action == ValidationErrorEventAction.Removed)
        ErrorCaption.Text = "";
    e.Handled = true;
}

[리스트 7. BindingValidationError를 이용한 데이터 유효성 검사 예제

지금까지 실버라이트 데이터 바인딩의 원리와 중요한 기능들을 살펴보았다. 물론 이것들은 데이터 바인딩의 가장 기초적인 부분이다. 보다 효과적인 사용을 위해서는 세심한 데이터 모델 설계와 UI의 구성, 그리고 무엇보다도 디자이너와의 협업이 중요하다. 다음 글에서는 데이터 바인딩을 보다 효과적으로 사용하는 방법과 디자이너와 협업하기 위한 방법에 대해 알아보도록 하겠다.

-----------------------------

다음호에 봐요 :D
Posted by gongdo
저는 네이버의 서비스 중에 카툰과 e-Sports 스타크래프트 프로리그 VOD/Live 서비스 밖에 안쓰는데요, 드디어 스포츠 중계와 VOD 서비스에 실버라이트가 도입되었어요.
저는 IE7/8을 깔았다 지웠다 했더니 Window Media Player를 사용했던 네이버 스포츠 중계 페이지에 들어가면 Media Player 9버전 이상을 설치하라는 메시지만 나오고 재생이 안되었거든요. 이제는 그런 메시지 따위 필요 없이 볼 수 있게 되었어요. :D

여튼 야구며 뭐며 있다는데 전 그런건 관심없고 스타 프로리그 보기로 고고씽.


네이버가 드디어 실버라이트를 도입했다는 건 실버라이트를 하는 입장에서 엄청나게 고무적인 사실인데요, 이미 프로야구 개막식 생중계에서는 하루만에 5만이라는 동접 제한을 꽉 채웠다고 해요. ㅎㄷㄷ...

Posted by gongdo

이 전 글에서 실버라이트 3에서 추가된 슈퍼 쿨한 기능 중 하나인 Behavior를 실버라이트 2에서도 구현할 수 있다고 살짝 언급했는데요, 어떻게 구현했는지 소개할께요. 소개에 앞서서 Behavior와 관련된 라이브러리 코드들은 모두 블렌드 3에 포함된 Microsoft.Expression.Interactivity 어셈블리를 리버스엔지니어링으로 카피한거에요. 사용시 참고하시길 바래요.

먼저 동작 완구 부터…http://shiverlight.net/sample/SilverlightInteractivity/


 

뭐어… 특별할 게 없어죠? 이 정도 기능이야 뚝딱뚝딱 코딩하면 10분도 안걸릴거에요. 그렇지만 여기 있는 모든 동작은 코딩이 단 한줄도 들어가지 않은 즉, 순수하게 XAML에서 Behavior와 Trigger만 사용한 거죠.

[샘플 코드]

그럼 구현 과정을 알아보죠.

1. Microsoft.Expression.Interactivity 어셈블리 복사

먼저 실버라이트 3 개발 머신에 블렌드 3를 설치하면 C:\Program Files (x86)\Microsoft Expression\Blend 3 Preview\Libraries\Silverlight 폴더에 Microsoft.Expression.Interactivity.dll 어셈블리가 있는데요, 이것이 바로 Behavior와 Trigger를 지원하기 위한 기반 클래스들을 담고 있죠. 이 파일을 실버라이트 2 개발 머신에 복사해두세요.

2. 리버스 엔지니어링

Microsoft.Expression.Interactivity 어셈블리를 Reflector등으로 까서 코드를 봅니다. 그리고 실버라이트 2 라이브러리 프로젝트를 하나 만들어서 거기에 옮기면 끝.

단, 여기에서 주의할 점이 있는데요, 블렌드의 희한한 이름 제한때문에 라이브러리 프로젝트의 이름은 반드시 Microsoft.Expression.Interactivity가 아닌 다른 이름을 써야 해요. 물론 코드에서 정의하는 네임스페이스의 이름은 아무거나 관계 없어요. 전 HugeFlow.Interactivity라는 이름을 붙여봤어요.

3. Behavior와 Action 만들기복사하기

Microsoft.Expression.Interactivity에는 Behavior와 Action을 위한 기반 클래스만 준비만 되어 있을 뿐, 실제로 동작하는 건 없어요. 제대로 동작하는지 확인하려면 만들어 줄 필요가 있는데요, Expression 갤러리에 보면 Microsoft의 Kirupa가 공개한 Sample Silverlight 3 Behaviors 라이브러리가 있어요. 당연히 이것은 실버라이트 3를 위해 만든 라이브러리이지만 Microsoft.Expression.Interactivity를 기반으로 하므로 우리가 리버스 엔지니어링 한 라이브러리와 호환이 돼요. 여튼 이 라이브러리를 다운 받아서 실버라이트 2 라이브러리 프로젝트로 만들어주면 준비는 끝.

4. 블렌드 3에서 테스트 프로젝트 만들기

이제 동작 완구에서 보이는 것처럼 코드를 짜기만 하면 되죠. 그렇지만 단순히 XAML로 이 모든 걸 작성하기엔 좀 귀찮은 생각이 들죠? 문법도 헤깔리고요. 당연히 XAML 디자인은 블렌드에서 하는 게 기본이에요. 그러나 블렌드2는 블렌드3처럼 Behavior나 Trigger와 관련된 기능을 지원하지 않아요. 그렇다면? 그냥 블렌드 3를 써서 디자인 하는거죠.

5. 블렌드 3에서 만들어진 XAML을 실버라이트 2 프로젝트로 복사하기

블렌드 3로 디자이너가 Behavior와 Action을 사용하여 이것저것 디자인한 후 만들어진 XAML을 그대로 실버라이트 2 프로젝트로 복사하세요. 그리고 XAML의 xmlns에서 Microsoft.Expression.Interaction 부분만 우리가 리버스 엔지니어링 한 라이브러리로 바꿔주면 끝.

하나하나 과정을 보일까 하다가 별로 중요한 작업은 아니라 결과물만 첨부했어요.

 

이렇게 만든 Interactivity 라이브러리의 장점으로는

  • 블렌드 3에서 Behavior와 Action 기능을 사용한 디자인을 그대로 복사하여 사용할 수 있다.
  • 블렌드 2에서도 디자인이 깨지지 않고 보인다.
  • 실버라이트 2 개발 환경에서도 아무 문제 없이 동작한다.
  • 실버라이트 2의 지저분한 코딩을 XAML로 수용할 수 있게 한다.
  • 가볍다. Interactivity 라이브러리의 용량은 겨우 36.5kb로 실제로 위의 샘플 애플리케이션의 XAP 파일은 33.3kb, 최적화하면 26.6kb밖에 안된다.

반면 물론 주의 할 점도 있어요.

  • 리버스 엔지니어링한 것으로 일단은 불법이다.
    (그렇지만 별로 문제 될 것 같지는 않습니다만… –_-)
  • 당연하지만 Behavior나 Action외의 ElementBinding이나 Effect와 같은 기능은 지원하지 않는다.

그 외엔 딱히 단점을 찾기 어렵네요^^

암튼, 실버라이트 3의 강화된 기능 중 일부는 이처럼 실버라이트 2에서 당장 사용할 수 있어요. 현업 개발자들은 실버라이트 3가 정식으로 릴리즈 될 때까지는 이런 방법을 적극적으로 활용하는 것도 좋을 거에요.

Posted by gongdo

요즘 실버라이트 3 나와서 바쁘게 공부하시는 분들이 많을 거에요. 저도 그러고 싶은데 아직 하고 있는 일이 많아서 거의 손을 못대고 있네요. 즉, 저처럼 현재 실버라이트를 업무로 하는 분은 실버라이트 3가 릴리즈될 때까지는 좋든 싫든 실버라이트 2와 블렌드 2를 써야 해요. 한 가지 좋은 소식이 있어요. 실버라이트 3가 엄청나게 많은 기능들을 추가했지만 그 중에 일부는 비트맵 이펙트처럼 실버라이트 2에서는 구현이 불가능한 것도 있지만 비헤이비어Behavior처럼 실버라이트 2에서도 비교적 간단하게 구현할 수 있는 것도 있다는거죠!

네, 저는 최근 앞으로 5개월 이상 사용할 실버라이트 2를 위해 실버라이트 3 코드에서 Behavior와 Action 그리고 Trigger를 옮기고 있어요. 이 기능들은 단순히 AttachedProperty를 비롯한 실버라이트 2에서 지원하는 몇몇 클래스로만 이루어져 있거든요.

그런데 이상하게 새로 만든 Trigger클래스가 실행도 잘되고 비주얼 스튜디오의 디자이너에서도 잘 보이는데 유독 블렌드(2)에서만 에러 화면이 나오는거에요. 아무리 Behavior와 Trigger가 좋다고 해도 블렌드와 충돌하면 의미가 없겠죠. 그래서 원인을 격리시키기 위해 새 솔루션을 만들고 클래스를 따로 분리해서 테스트하다가 재밌는 사실을 발견했어요.


바로 프로젝트의 이름 즉, 어셈블리의 이름이 Microsoft.Expression로 시작할 경우 블렌드가 그 어셈블리에 있는 클래스를 못 찾아온다는 사실이에요.

그런데 더 재밌는 건 어셈블리의 이름이 Microsoft.Expression까지만 썼을 경우는 동작하고요, 당연히 다른 이름을 쓸 때도 잘 동작한다는 거에요. 오직 Microsoft.Expression.XXXXXX라는 이름을 가진 어셈블리만 이 문제가 발생해요. 그리고 네임스페이스의 이름은 이 현상에 어떤 영향도 주지 않고요.

…후우… 이것 때문에 몇 시간을 썼는지…

그래서 결론이 뭐냐면요, 혹시 마이크로소프트에서 나온 라이브러리를 베껴쓸 때에는(…) 적어도 어셈블리 이름은 바꿔서 쓰라는거죠. 도둑질도 배워야 한다나요. ㅎㅎ

Posted by gongdo

What’s New in Microsoft Silverlight 3 : http://videos.visitmix.com/MIX09/T14F 참고 :D

Silverlight 3 툴 지원

  • Visual Studio 2008 Tools for Silverlight 3 beta/RTM
    • XAP 압축률 향상
      • 10~30% 감소된 XAP파일 크기
    • 인터랙티브 디자이너
      • Visual Studio 2010에서 지원 예정
  • Expression Blend 3 preview
    • 최종 버전은 올해 말

Media Format 지원

  • H.264/AAC/MP4 디코더 지원
  • 산업 표준 포맷으로 광범위하게 사용되고 있으므로 지원하기로 결정
  • H.264 파일로 할 수 없는 것
    • DRM 지원
    • Windows Media Server에서 스트리밍 호스팅

GPU 가속 지원

  • 옵트인 기능 즉, 명시적으로 사용할 것을 지정해야 함
    • Param으로 EnableGPUAcceleration, EnableCacheVisualization를 true로 설정
    • 최종 서피스 렌더링에 GPU를 사용
  • 엘리먼트 마다 옵트인으로 적용
    • CacheMode="BitmapCache"로 설정해야 함
    • 여러 개의 엘리먼트가 조합되어 렌더링 될 때 GPU를 사용
    • 엘리먼트를 늘릴 때(Stretch) GPU를 사용
  • 브라우저와 full-screen 모드에서 모두 동작
  • GPU 가속이 가능한 클라이언트에서 성능 향상
    • 다른 어떤 비주얼도 수정하지 않아도 됨

(데모)
미디어 관련 : T43F, T19F, T56F
GPU 관련 : T17F

Perspective 3D(Projection)

  • Perspective 3D
    • 2D 오브젝트를 3D 공간에 배치
    • X,Y,Z 회전 및 X,Y,Z 회전 축 지정
    • 지역/전역 X,Y,Z 옵셋 지원
  • Element.Projection
    • 현재는 PlaneProjection만 지원

애니메이션 가속도 지원

  • 기본 지원되는 애니메이션 가속도 함수
    • CircleEase, SineEase, BackEase
    • ExponetialEase, PowerEase
    • QuadraticEase, CubicEase
    • QuarticEase, QuinticEase
    • ElasticEase, BounceEase
  • 커스텀 가속도 함수도 작성 가능
    • 자신만의 가속도 함수를 사용 가능

비트맵 이펙트와 픽셀 셰이더

  • 이펙트
    • 비주얼의 동작에 영향을 줌
    • 기본 지원되는 이펙트
      • Blur, DropShadow
  • 커스텀 이펙트
    • 커스텀 이펙트는 Shader로 구현됨
    • HLSL이라는 표준 코드를 사용
      • DX SDK 유틸리티를 사용하여 byte code로 컴파일
      • 실버라이트 3는 컴파일 된 byte code를 사용
    • 셰이더는 UI 엘리먼트가 렌더링 되기 전에 각각의 픽셀을 변경할 수 있는 기회를 제공
    • 셰이더 = 픽셀 단위 함수 혹은 명령
    • (Green screen 등)

픽셀 API

  • 두 개의 파츠
    • 동적 비트맵 생성
      • WriterbleBitmap
      • 비트맵에 있는 픽셀을 읽고 쓰기
    • 비주얼 트리를 비트맵에 렌더링하기
  • 시나리오
    • 동적인 이미지 생성(실시간 그래프 등)
    • 이미지 편집 및 효과
    • 비주얼 복사
      • reflections, drag effect 등

Raw 오디오/비디오 API

  • 픽셀 API와 비슷하지만 오디오/비디오를 위한 기능
  • 시나리오
    • 동적으로 사운드 생성
    • 커스텀 오디오/비디오 디코더 작성(DIVX, XVID 등)

자세한 데모 : T17F

로컬 메시징 지원

  • 실버라이트 플러그인 간 데이터 통신
    • 같은 페이지에 있는 여러 플러그인
    • 다른 브라우저 탭에 있는 여러 플러그인
    • 다른 브라우저에 있는 여러 플러그인
  • 구현
    • 공유 메모리(Shared memory)로 구현
    • "named pipes"와 같이 노출됨
    • 문자열 기반의 메시지

UI Framework 향상

  • 리소스 병합 기능(Merged Resource Dictionaries)
  • BasedOn 스타일(스타일 구조화)
  • 런타임에 스타일 변경 가능
  • 다중 선택 리스트박스
  • "Handled"된 라우트 이벤트를 수신하는 것이 가능
  • VSM에 "Invalid" 상태 추가
    • 입력 상태가 유효하지 않을 때를 의미
    • TextBox, CheckBox, ComboBox, ListBox, RadioButton 등

상세 : T16F

기타 향상

  • SystemColors
    • 플랫폼에서 사용중인 색상 테마
  • FileSaveDialog 지원
    • 명시적인 UI를 통한 저장 위치 결정 다이얼로그를 통해 파일 위치 결정
    • 보안상의 이유로 유저가 선택한 파일을 열고 쓸 수만 있음
  • 텍스트 향상
    • 클리어 타입 텍스트(베타 이후에 지원 예정)
    • CaretBrush(텍스트 박스 안에 있는 커서)
    • 텍스트 애니메이션을 위한 최적화 옵션
      • 텍스트가 정확한 픽셀에 정렬하기 위해 걸리는 것을 선택 가능
    • Glyphs도 시스템 폰트를 지원
  • 이미지 정렬

새 SDK 컨트롤

  • DockPanel, Expander, Label, TreeView, ViewBox, WrapPanel, ChildWindow, DatePickerTextBox, TabPanel
  • +기타…

그 외 중요한 추가 사항

  • 비즈니스 관점의 지원
    • 내비게이션 프레임워크(Frame, Page 모델)
    • 데이터 건트롤
    • SEO(검색 엔진 최적화) 지원
    • N-Tier 데이터 모델 지원
    • T40F 참고
  • WebService 스택 향상
    • Binary XML, SOAP faults, Credentials 지원
    • T42F 참고
  • Silverlight Toolkit
    • T15F 참고

"Out of the Browser" 지원

  • 실버라이트를 브라우저 바깥에서 실행 가능
    • 그러나 일반 애플리케이션과는 다르게 철저하게 Sandbox 보안 모델 내에서 실행됨
    • 브라우저에서 실행하는 것과 정확하게 동일한 보안 모델 및 사용성을 가짐
  • 실버라이트 코어 런타임에 통합
    • 브라우저 바깥에서 실행 될 때 SilverlightLauncher가 실행되고 그 위에서 동작
  • 애플리케이션 단위로 사용 가능
    • Manifest에 애플리케이션을 설명
    • Deployment.ApplicationIdentity
  • 설치 경험
    • 우클릭하여 Install 선택
      • 데스크탑과 프로그램 그룹에 추가할지 여부 선택
    • 또는 설치를 위해 커스텀 버튼을 추가 가능
      • Application.Current.Detach
    • 삭제는 단순히 우클릭 후 Uninstall 한방으로 끝
  • 새 네트워크 API
    • 연결/연결 안됨 상태
    • 상태 변경됨 이벤트
  • Offline API
    • 브라우저에서 실행되었는지 브라우저 바깥에서 실행되었는지 상태
      • Application.Current.RunningOffline
    • 업데이트 API 등
      • 기본적으로 Online상태일 경우 새 버전의 XAP을 자동으로 설치
  • 비즈니스 관점의 지원
Posted by gongdo

음… 한 달 전에 월간 마이크로소프트에 실버라이트 데이터 바인딩에 대해 기고를 했는데요, 3월호에 실렸더군요. 전 모르고 있었는데…(이건 뭔가… ┐─) 이 글은 총 3회로 나누어 쓴 글로 현재 2회까지 기고를 했고 아마 4월호에 두 번째 내용이 나갈거에요. 글의 저작권은 제게 있지만 월간 마이크로소프트가 나오면 그 때 올리도록 할께요.

--------------------------

데이터의 표현과 로직의 분리

표현과 로직의 분리. 얼마나 아름다운 말인가! 그러나 우리는 십수년간 사용해왔던 HTML의 경험으로부터 결코 쉽지만은 않다는 걸 배웠을뿐이다. 그렇지 않은가? 여러분은 디자이너가 만든 HTML 레이아웃을 손대지 않고 얼마나 작업할 수 있는가? 여러분은 데이터의 표현을 얼마나 협업의 고통 없이 수정할 수 있는가?

실버라이트가 출시된지도 벌써 2년이 다 되어간다. 결코 긴 시간은 아니지만 경험을 쌓기엔 충분한 시간이다. 현장에서 접하는 실버라이트는 어떤 모습인가? 필자를 포함한 얼리어답터들이 주장하던 것 처럼 정말로 표현과 로직이 잘 분리되어 디자이너와 개발자가 원활한 협업을 하고 있는가?

필자의 답은 ‘아니오’이다. 우리는 여전히 HTML 시절에 겪었던 문제를 고스란히 안고 있고 여전히 디자이너의 결과물을 개발자가 망치고 있으며 데이터의 표현이 변경될 필요가 있을 때 디자이너와 소모적인 코드 수정을 하고 있다. 다만 HTML에 비해 레이아웃이나 표현을 하기가 쉬워졌고 엄격한 XML 문법으로 인하여 구조적인 문제가 줄었을 뿐이다.

그렇다면 도대체 무엇이 문제일까? 단지 디자이너가 툴에 익숙하지 않아서 협업이 이루어지지 않는다고 말한다면 그것은 ‘비겁한 변명’일 것이다. 필자는 실버라이트가 표현과 로직을 분리하기 위한 도구와 기법들을 제공함에도 불구하고 별반 나아진게 없는 문제의 원인을 패러다임의 변화에 적응하지 못하는 우리 개발자에게 돌리고 싶다. 그러나 처음부터 너무 비관적으로 될 필요는 없다. 문제를 발견했다면 그것을 해결할 뿐. 오히려 문제를 푸는 과정이 재밌다고 느껴지지 않는가? 기존의 경험으로부터 정리된 통찰을 이끌어내는 과정은 짜릿하지 않은가?

물론 모든 문제를 해결하는 마법 같은건 존재하지 않지만 적어도 몇몇 문제를 해결하는 좋은 방법 정도는 존재하는 법이다. 앞으로 연재될 이 글을 통해 데이터의 표현과 로직을 보다 효율적으로 분리하는 방법을 연구해보고 아주 조금이라도 디자이너와 개발자가 협업의 고통을 줄였으면 하는 바램이다.

처음 기고하다 보니 의욕이 넘쳐 서론이 길었다(^^a). 그럼 본격적으로 데이터와 표현과 로직을 분리하기 위해 반드시 익혀야 할 실버라이트의 데이터 바인딩에 대해 연구해보자.

전형적인 데이터 표현 과정

메신저나 커뮤니티 회원 명부 등에서 볼 수 있는 회원 카드 애플리케이션을 생각해보자. 단순하게 ID, 사진, 이메일 주소, 블로그 주소, 생일 정보 정도면 충분할 것이다. 필자는 다음과 같은 구조의 프로젝트를 만들어 봤다.


[그림 1. 샘플 프로젝트의 구조]

먼저 데이터를 다루는 Model 폴더에는 회원 정보 클래스인 Profile.cs가 있고 회원 정보를 제공하는 서비스를 시뮬레이션하는 MockProfileService가 있다. 물론 제대로 하려면 웹 서버를 구축하여 서버에서 데이터를 가져와야 겠지만 그렇게 구성되었다고 가정하겠다. MockProfileService는 다음과 같이 회원 정보를 랜덤하게 반환하는 GetAnyProfile 메서드와 주어진 회원 정보를 업데이트하는 UpdateProfile 메서드를 노출하고 있다.

public Profile GetAnyProfile() //생략
public void UpdateProfile(Profile profile) //생략

[리스트 1. MockProfileService 클래스가 노출하고 있는 메서드]

다음으로 회원 카드를 보여주기 위한 유저 컨트롤인 CardView가 View폴더에 있다. 익스프레션 블렌드를 사용하여 다음과 같이 간단하게 디자인했다.


[그림 2. 간단한 회원 카드 디자인(말할 것도 없이 엉망이다.)]

디자인은 IdLabel, ProfileIamge, BritdayInput과 같이 직관적인 이름으로 오브젝트를 배치했다. 뭔가 아니다 싶은 디자인이 보이는가? 이것이 필자가 개발자라는 직업을 선택한 이유 중 하나이다. 어쨌든 지금은 디자인의 품질이 중요한게 아니므로 이쯤하고 넘어가도록 하자.

앞에서 디자인한 유저 컨트롤의 코드 비하인드인 CardView.xaml.cs 파일을 열어보면 Profile 속성을 설정했을 때 해당 회원의 데이터를 화면에 보여주고, 또한 TextBox의 Text속성이 변경되었을 때 ProfileUpdated 이벤트를 던지는 코드가 작성되어 있다.

private Profile _profile;
public Profile Profile
{
    get { return _profile; }
    set
    {
        _profile = value;
        // 입력 받은 정보로 UI를 업데이트
        IdLabel.Text = _profile.Id;
        BirthdayInput.Text = _profile.Birthday.ToString("yyyy-MM-dd");
        EmailInput.Text = _profile.Email;
        BlogInput.Text = _profile.Blog;
    }
}

// 입력창의 포커스가 벗어났을 때 값을 변경하는 코드들
void BirthdayInput_LostFocus(object sender, RoutedEventArgs e)
{
    Profile.Birthday = DateTime.Parse(BirthdayInput.Text);
    FireProfileUpdated();
}

[리스트 2. CardView의 코드 비하인드에 작성된 지루한 코드의 일부]

마지막으로 루트 비주얼인 Page.xaml에는 버튼 하나와 MyCard라는 이름의 CardView 하나를 올려놓았고 Page의 코드 비하인드인 Page.xaml.cs를 보면 MockProfileService의 인스턴스를 하나 만들어놓고 컨트롤이 초기화되거나 버튼을 클릭했을 때 서비스의 GetAnyProfile 메서드를 호출하여 MyCard의 Profile 속성을 설정하게 되어 있으며, MyCard에서 ProfileUpdated 이벤트가 발생했을 때 MockProfileService의 UpdateProfile 메서드를 호출하여 변경된 데이터를 업데이트하고 있다.

솔루션을 빌드하고 실행해 보면 버튼을 클릭할 때마다 샘플로 작성한 데이터 중 하나를 랜덤으로 표시하는 것을 볼 수 있고 텍스트 박스 중 하나를 변경하면 변경된 데이터가 실행되고 있는 동안에는 유지되는 것을 확인할 수 있다. 자세한 코드와 동작은 다운로드 받은 파일의 압축을 풀고 [DataBinding Take1] 폴더에 있는 소스코드를 열어 직접 확인하길 바란다.


[그림 3. 회원 카드 애플리케이션의 동작 화면]

어쨌든 이 애플리케이션은 잘 동작한다. 실무에서 이 정도 코드면 충분하다. 아니, 충분했었다. 그럼 도대체 무엇때문에 잘 동작하는 코드를 바꿔야 할까? 이 프로젝트는 협업과 유지보수의 관점에서 적어도 네 가지 이상의 문제점을 가지고 있다. 여러분도 읽기 전에 한 번 생각해보길 바란다.

  • 불필요한 임시 데이터가 XAML에 직접 하드코딩 되어 있다. 혹시 임시 데이터라고 아무렇게나 데이터를 넣었다가 실제 런타임에 고객에게 노출된 적은 없는가?
  • 디자인에 들어가야 할 구성요소의 종류가 강제되고 있으며 이름을 정확히 맞춰주지 않으면 CardView.xaml.cs에 있는 코드는 무용지물이 된다. 디자이너의 표현력이 코드 때문에 제한받고 있지 않은가?
  • CardView에서 Profile 속성의 세터(setter)를 보자. Profile 데이터 하나하나를 다시 설정하고 있다. 만약 더 많은 속성이 추가되거나 변경된다면 그때마다 이렇게 단순 반복적이고 소모적인 코드를 다시 작성하고 싶은가?
  • 디자인이 변경되었을 때 역시 이 과정을 다시 반복할 것인가?
  • 또한 입력한 값이 유효한지 확인하는 처리까지 들어간다면 복잡도는 더욱 늘어날 것이다.

데이터 바인딩 예제

데이터 바인딩은 컨트롤의 특수한 속성과 XAML의 몇 가지 표현식을 사용한다. 데이터 바인딩을 설명하기 전에 먼저 사용 예제를 보도록 하자. 앞에서 작성한 코드에서 아주 조금만 고쳐도 상당히 쾌적해진다. 물론 모든 문제를 한꺼번에 해결할 수는 없지만 하나씩 단계적으로 잡아 나가도록 하겠다. 역시 자세한 코드는 [DataBinding Take2 - binding basic] 폴더의 코드를 참고하길 바란다.

먼저 CardView에 작성했던 지루한 설정/업데이트 코드들을 시원하게 날려버리자. 컴포넌트 초기화를 제외한 모든 코드를 말 그대로 지우면 된다. Profile을 받고 XAML에 어떤 디자인에 어떻게 설정해야 할지 고민할 필요가 없다.

public partial class CardView : UserControl
{
    public CardView()
    {
        InitializeComponent();
    }
}

[리스트 3. CardView.xaml.cs: 단순해진, 아니 텅비게 된 CardView의 코드 비하인드]

앞의 코드를 제거하면 업데이트 등으로 사용했던 이벤트가 삭제되어 Page.xaml.cs에서 오류가 발생한다. 여기에서도 불필요한 이벤트 처리등을 제거하자. 다만 버튼을 클릭하여 회원 정보를 다시 받아야 할 때 다음과 같이 MyCard의 DataContext 속성을 설정하기만 하면 된다.

private void UpdateProfile()
{
    // 서비스 호출(웹 서비스 등의 호출을 통해 받았다고 가정)
    Profile profile = _service.GetAnyProfile();

// 회원 카드의 정보 업데이트
    MyCard.DataContext = profile;
}

[리스트 4. Page.xaml.cs: CardView에 대한 의존성이 줄어든 Page의 코드 비하인드]

CardView의 인스턴스인 MyCard를 사용하는 곳이 UpdateProfile 메서드 단 한 곳으로 줄었다. 나중에 뭔가 변경이 생기더라도 간편하게, 대부분은 전혀 손대지 않고도 적용이 가능할 것이다.

다음으로 DataContext에 설정된 회원 데이터를 CardView에 보여줘야 한다. CardView.xaml에 데이터 바인딩 표현식을 사용하여 데이터를 표시하면 된다. 지면 관계상 핵심적인 부분만 표시하였다.

<TextBlock Text="{Binding Id}" />
<Image Source="{Binding Picture}" />
<Grid >
        <TextBlock Text="Birthday" />
        <TextBox Text="{Binding Birthday, Mode=TwoWay}" />
        <TextBlock Text="Email" />
        <TextBox Text="{Binding Email, Mode=TwoWay}"  />
        <TextBlock Text="Blog" />
        <TextBox Text="{Binding Blog, Mode=TwoWay}" />
</Grid>

[리스트 5. CardView.xaml: Binding 표현식으로 설정된 CardView]

센스있는 독자라면 굳이 설명하지않더라도 위의 코드가 무엇을 의미하는지 눈치 챘을 것이다. <TextBlock Text="{Binding Id}" …/> 코드를 예로 들어 간단하게 말로 하자면 “TextBlock의 Text 속성을 Id라는 이름을 가진 속성으로 바인딩(Binding)한다.”라고 할 수 있다. 물론 여기에서 Id라는 이름을 가진 속성은 CardView 유저 컨트롤의 DataContext에 설정된 데이터에서 가져오는 것임은 말 할 것도 없다.

아래쪽에는 좀 더 흥미있는 표현식이 보이는데, <TextBox Text="{Binding Birthday, Mode=TwoWay}" …/> 코드를 예로 들자면 “TextBox의 Text 속성을 Birthday라는 이름을 가진 속성으로 바인딩하되, 바인딩 모드는 양방향(TwoWay)로 한다.”라고 할 수 있다. 여기에서 TwoWay라는 모드는 그 이름에서 추측할 수 있듯이 바인딩 된 대상 오브젝트의 속성이 변경될 경우 역으로 바인딩 된 원본 데이터의 속성도 변경시켜 서로 동기화시킨다는 의미이다. 보통 TextBox나 CheckBox, RadioButton과 같이 사용자가 값을 입력하거나 선택할 수 있는 컨트롤의 속성에 많이 이용된다. 실행결과는 당연하게도 앞의 프로젝트와 동일하다.


[그림4. 데이터 바인딩을 사용한 실행 화면]

자 어떤가? 데이터 바인딩을 사용하여 50라인이 넘는 코드를 삭제하고 아주 단순한 코드와 표현식만으로 서비스에서 받은 데이터를 효과적으로 표시하는 것이 가능해졌다. 특히 CardView의 XAML 코드에는 x:Name이라는 속성 없이도 데이터를 표현하는 것이 가능하므로 디자이너가 더 이상 개발자와 골치아픈 이름 짓기 문제로 싸울 필요가 없게 되었다. 물론 의미가 있는 오브젝트에 x:Name으로 그 오브젝트를 설명하는 것은 훌륭한 시도이다. 그러나 이 이름은 어디까지나 참고일 뿐이지 실제 코드 작성에 반드시 필요한 것이 아니므로 디자이너든 개발자든 마음대로 이름을 지어도 된다. 이것만으로도 행복하지 않은가!

또한, CardView를 제어하고 CardView에서 일어나는 동작을 감시하여 별도의 처리를 해줘야 했던 Page 유저 컨트롤 역시 CardView와의 의존성이 줄어들고 CardView에게 필요한 데이터를 줘 버리고 모른척할 수 있게 되었다. 서로의 의존성을 줄이는 것, 이것이야말로 개체지향 프로그래밍의 성배가 아니었던가!

물론 여기에는 문제점도 남아있다. 블렌드로 CardView 유저 컨트롤을 열어보자.


[그림5. 데이터 바인딩된 유저 컨트롤의 모습]

데이터 바인딩을 위해 사용한 표현식때문에 앞에서 임시로 넣었던 데이터는 온데간데가 없다. 다만 해당 속성에는 데이터 바인딩을 사용하고 있음을 알리는 노란색 테두리가 있을 뿐. 이래서야 디자이너가 디자인을 변경할 때 결과물을 쉽게 예측하기 어렵다. 아니, 불가능하다.

또한 데이터 바인딩을 사용한 실행 결과를 보면 날짜 필드가 우리가 기대한 것과는 달리 년/월/일만 나온게 아니라 월/일/년에 시간까지 나온다. 이래서야 단순 바인딩은 제대로 쓸 수 없다.

사실 필자도 처음에는 이런 문제점 때문에 데이터 바인딩을 사용하지 않았었다! 그렇다면 데이터 바인딩으로 디자이너와의 협업을 보다 원활하게 한다는 필자의 말이 거짓이란 말인가. 물론 아니다. 필자는 앞으로 진행되는 연재를 통해 이 문제를 우아하게(?) 해결하는 법을 소개하고자 한다. 물론 데이터 바인딩을 소개하기 위해 건너뛴 데이터 바인딩의 이론적인 기초 및 중요한 문법에 대해서도 소개할 것을 약속한다.

참고 자료

Posted by gongdo

매년 MIX에서는 실버라이트에 대한 굵직한 릴리즈와 정보가 쏟아지죠. 이번 MIX09에서는 드디어 Silverlight 3가 베일을 벗었어요. 2가 나온지 얼마나 되었다고 벌써 3가 다가오고 있죠. 물론 잦은 릴리즈가 현업에 압박으로 다가올 수도 있지만 개발 프로세스를 잘 준비한다면 2에서 할 수 있는 것과 3에서만 되는 것… 이렇게 구분을 하여 대응할 수 있을거에요.

마이크로소프트는 실버라이트의 릴리즈 주기를 9~12개월로 빠르게 한다는 계획을 발표한 적도 있는데요, 그만큼 RIA의 개발이 정형화되지 않았기에 그만큼 현업의 요구를 빠르게 수용하겠다는 의미로 받아들일 수도 있죠.

앞으로의 실버라이트의 큰 뼈대는 2를 기반으로 계속하여 새로운 기능이 추가되는 형식이다…라고 얘기들 하는데요, 물론 닷넷 코드 베이스라는 개발 프로세스를 놓고 보면 맞는 말이지만, 솔직히 제 느낌으로는 오프라인 지원 등의 너무나도 굵직한 내용 때문에 3를 기반으로 새로운 기능이 추가되거나 향상된다… 라고 얘기하고 싶어요.

어쨌든, 실버라이트 3가 제게 강한 인상을 주는건 단순히 새로운 기능들 때문이 아니에요. Perspective 3D, 비트맵 프로세싱, GPU 가속, H.264 지원(아직 불완전하지만), 오프라인 및 데스크탑 설치 지원, 폰트 가독성의 지속적인 향상, 더 많은 컨트롤 지원, 스타일 병합, 브라우저 스택을 사용하지 않는 순수 HTTP 요청, 블렌드 3의 비약적 향상, 데이터 친화적인 개발 환경… 이것들은 바로 실버라이트 2에서 Adoption Blocker로 작용하던 요소들이었고 실버라이트 3는 이런 요소를 적극적으로 해소하기 시작한 첫 버전이라고 생각해요. 전에 없이 현업의 요구사항과 개발 커뮤니티에서 나온 훌륭한 실험 결과를 적극적으로 그리고 대규모로 수용한 첫 버전이란 말이죠.

실버라이트 1.1과 2에서는 사실 몇몇 시나리오에서 필요한 기능을 중심으로 홍보되었고 또 사용되었어요. 바로 미디어와 딥줌이죠. 물론 텍스트 지원 향상, 컨트롤 모델 지원 등의 굵직한 내용도 있었고 미디어와 딥줌 외의 다른 분야에도 시도된 사례가 많지만 상업적으로 의미가 있었던 건 역시 미디어와 딥줌 뿐이었다고 생각해요.
(그간 다른 곳에 적용하려고 얼마나 삽질을 했었던지 =_=)

실버라이트 3는 이제 그간 플래시만이 독보적인 지위를 차지하고 있던 모든 RIA 시장에 참가할 수 있게 되었어요. 뿐만 아니라 깜짝 놀랄만한 오프라인/데스크탑 설치 시나리오 지원으로 AIR만이 할 수 있었던 그것도 가능해졌죠. 비공식적이기도 하고 물론 짜는 사람에 따라 다르겠지만 단순한 코드 실행 성능은 이미 실버라이트 2가 앞서 있다는 점을 감안했을 때 앞으로의 상황이 너무나도 기대되고 흥분돼요.

자, 좋은 얘기는 다 했고 아쉬운 점을 얘기해보자면… 웹 카메라와 마이크로폰! 최근 닌텐도 DS에도 채용되어 더욱 재밌는 사용자 경험을 제공할 수 있는 기회가 아쉽게도 다음으로 미뤄졌어요. 뭐 크게 아쉬운 기능은 아니지만서도 말이죠. 다음으로 블렌드. 물론 이번에 엄청난 기능 향상과 추가가 있었지만 제가 보기엔 (아직 써보지 않았어요) 아주 자잘한 인터랙션들은 크게 개선되지 않은 것 같아요. 예를 들어 타임라인에서 키프레임을 드래그하여 선택한다거나 하는… 사실 없어도 못쓰는 건 아니지만 그런게 디자이너의 접근을 막는 요소이기도 하죠. 여튼 이 얘기는 글로벌 서밋때도 나왔으니 아마도 개선될 거에요.

아직 써보지도 않고 써내려간 얘기라 기대감이 더 크네요. 부디 2 베타때 겪었던 엄청난 버그의 홍수는 없길 바라면서 버추얼 머신에 실버라이트 3 개발환경을 설치하며 주절거려봤어요. Silverlight Rocks! XD

Posted by gongdo

그간 몇몇 업체들에 실버라이트 교육을 다니면서 쌓아두었던 Hands On Lab 자료를 방출합니다. 사실 네이버 실버라이트 카페에는 이미 자료로 올라와 있는 상태인데, 정작 제 블로그에는 안올렸더군요.^^

핸즈온랩은 아주 기초적인 부분을 하나하나 설명하는게 아니라 그냥 순서대로 따라하면서 익힐 수 있도록 준비했어요. 실전은 감이 중요하달까요? 대략 아래의 내용이 준비되어 있고 계속 추가할 예정(어디까지나 예정 ㅋㅋ). 잘게 쪼갠건 물론 포스팅 개수를 늘리기 위해서아주 짧은 시간 동안 하나씩 클리어하는 기분을 느껴보시라는 배려에요(…).

번호가 안정해진 건 언제 할지 모른다는 얘기. 암튼 계속 연재할 수 있도록 부담을 팍팍 밀어주세요.^^

Posted by gongdo


티스토리 툴바