2010.01.27 09:00

1.RichTextArea Part 1
2.RichTextArea Part 2
3.Accessing Web Camera and Microphone
4.Right Click Mouse Events

5.MouseWheel API

6.Using Silverlight Controls As Drip Targets
7.DataGrid Enhancements
8.Printing API Basics 
9.Hosting HTML Content

10.Accessing the Global Clipboard Programmatically

11.Using the ViewBox Control
12.Asynchronous Data Validation 
13.BiDi and Right-to-Left Support 
14.Notification API
15.Local File Access 
16.RIA Services support in Visual Studio 2010 

블로그 이미지 김영욱 차장 Microsoft Korea  .NET Evangelist
Enterprise UX 를 위한  UI 기술과 SOA, Cloud Computing, NUI등 다양한 분야의 접목과 응용을 통해 최적의 IT 인프라 구축을 위해서 노력하고 있다.
Email: iwinkey@hotmail.com
Blog: http://winkey.tistory.com

 

이번 시간에 설명해 드리는 내용은 Silverlight에서 비동기적으로 데이터의 내용을 검증하는 것에 대한 내용입니다.

ASP.NET 등에서는 데이터의 내용을 검증하는 컨트롤들이 제공되고 있어서 비교적 쉽게 데이터의 내용을 검증하는 작업이 가능하지만 Silverlight에서는 아직 검증(Validation)과 관련된 컨트롤이 따로 제공되지 않고 있습니다.

 

<그림1> 비동기 검증에 대한 기법을 보여주는 샘플

 

검증 작업을 자동으로 처리해주는 컨트롤이 없으면 일일이 코딩으로 처리해 주어야 하기 때문에 이번에 설명할 내용은 꽤 코드 위주로 진행 될 예정입니다. 또 대부분은 Silverlight 4가 아니더라도 적용 가능하기 때문에 본 내용은 Silverlight를 사용하는 대부분의 개발자들에게 도움이 되는 내용입니다.

 

 

1. 왜 비동기 적인 검증을 하는가?

 

비동적인 검증을 하는 이유는 여러 가지 이유가 있을 수 있지만 가장 중요한 이유는 사용자들의 작업을 최대한 방해하지 않는다는 것입니다. 사용자의 작업을 최대한 방해 하지 않으면서 자연스럽게 잘못된 입력을 알려는 방법으로 비동기 검증을 이야기 하고 있습니다.

물론 경고 창이 별도로 팝업되고 사용자들의 확인을 요구하는 것은 부적절하고 쓸데 없는 클릭을 유발합니다.

 

<그림2>자연스러운 입력 오류의 안내

 

<그림2>를 보면 팝업이 발생하지 않는 방법으로 사용자들에게 입력 오류가 발생한 컨트롤의 위치와 오류의 내용을 설명하고 있는 것을 볼 수 있습니다. 이런 작업을 가장 적절하게 해결 할 수 있는 방법은 바로 사용자 정의 컨트롤을 제작하는 것입니다. 여기서는 EditCustomer라는 사용자 정의 컨트롤을 제작하겠습니다.

 

 

2. 사용자 정의 컨트롤을 만들어 보자.

 

사용자 정의 컨트롤을 만들 때는 반복적으로 사용되거나 혹은 동적으로 변화하는 UI영역, 혹은 이벤트 핸들링이 필요한 경우 등 다양한 목적으로 인해서 만들게 됩니다. 여기서는 이벤트 핸들링을 목적으로 EditCustomer라는 사용자 정의 컨트롤을 만들어 보려고 합니다.

 

<그림1>에서 볼 수 있는 영역 자체가 지금 만들려고 하는 EditCustomer 컨트롤 입니다. 메인 페이지에서 해당 폼을 불러서 사용하기 위해서 아래와 같이 코드를 이용할 수 있습니다.

 

EditCustomer wind = new EditCustomer();
wind.VerticalAlignment = System.Windows.VerticalAlignment.Top;
wind.Margin = new Thickness(0, 50, 0, 0);
wind.Show();

 

본격적으로 코딩에서 들어가기 전에 EditCustomer는 System.Windows.Controls.ChildWindow로 부터 상속을 받게 합니다. ChildWindow는 Silverlight 안에서 하나의 팝업 창의 역할을 할 수 있게 해주는 컨트롤로 앞으로 많이 활용 될 것으로 기대되는 컨트롤 중 하나 입니다.

 

<소스1>ChildWindow로 부터 상속

 

EditCustomer 사용자 컨트롤이 Load되고 나면 기본적인 이벤트 핸들러 들을 붙이기 시작하는데 그 이전에 보면 theWindow, theCustomer에 각 각 값을 대입하고 있는 것을 볼 수 있습니다.

<소스2>theWindow와 theCustomer의 사용

 

그런데 자세히 보면 theWindow에는 자기 자신을 집어 놓고 있고 theCustomer에는 CCustomer.RandomCustomer를 대입하고 있는 것을 볼 수 있는데 여기서 theWindow는 정적인 맴버 변수로 외부에서 자기 스스로를 잘 참조할 수 있게 추가한 구문입니다.

 

<소스3>맴버 변수인 theWindow

 

이와는 상관없이 theCustomer는 LayoutRoot.DataContext에 설정하는 것을 볼 수 있는데 이는 해당 되는 Entity Class를 해당 폼에 바인딩 시키기 위함입니다.  하지만 그냥 Entity class가 아닌 게 데이터만 가지고 있지 않고 이벤트도 가지고 있기 때문입니다. 해당 되는 Customer의 값이 바뀌면 발생되는 이벤트로 ChangeStatus를 가지고 있습니다.

 

<소스4>theCustomer_ChangeStatus 이벤트 핸들러

폼에 해당 Entity class가 바인딩 되어 있는 상태에서 사용자의 폼의 내용을 수정할 경우 Entity class도 변경되고 이와 관련된 이벤트가 발생되게 되는데 이는 그냥 되지는 않고 Customer class에서 해당 이벤트를 정의해 주었기 때문에 가능한 것입니다.

 

어찌되었던 변경이 감지되면 해당 상태에 맞추어서 메시지를 출력할 수 있게 해주는 코드가 <소스4>에 나와있습니다.

메시지를 내보는 메소드인 WriteToLog( )는 Log라는 ListBox에 아이템을 추가하는 방식으로 구현되어 있습니다.

 

<소스5>WriteToLog ( )

 

이제 Customer Class의 내용을 살펴보면 아까 사용했던 이벤트를 정의하는 부분이 있습니다.

<소스6>Customer class의 이벤트 델리게이트

 

이제 검증과 관련된 작업이 거의 끝났습니다.

정리해 보면 다음과 같이 요약 할 수 있습니다.

 

검증이 필요한 컨트롤을 사용자 정의 컨트롤로 만들고 Entity class를 설계하고 이때 이벤트 델리게이트를 사용해서 이벤트를 추가하고 해당 이벤트가 비동기적으로 발생할 때 마다 검증과 동시에 사용자에게 검증 결과를 알려주는 것입니다.

 

사소 소스가 불편하고 어려운 점들이 있어 보이는데 후에 좀 더 사용하기 쉬운 소스를 만들어볼까 합니다.

 

역시 나머지 내용은 첨부된 소스를 참조해 주시기 바랍니다.

신고
2010.01.26 09:00

1.RichTextArea Part 1
2.RichTextArea Part 2
3.Accessing Web Camera and Microphone
4.Right Click Mouse Events

5.MouseWheel API

6.Using Silverlight Controls As Drip Targets
7.DataGrid Enhancements
8.Printing API Basics 
9.Hosting HTML Content

10.Accessing the Global Clipboard Programmatically

11.Using the ViewBox Control

12.Asynchronous Data Validation 
13.BiDi and Right-to-Left Support 
14.Notification API
15.Local File Access 
16.RIA Services support in Visual Studio 2010  

블로그 이미지 김영욱 차장 Microsoft Korea  .NET Evangelist
Enterprise UX 를 위한  UI 기술과 SOA, Cloud Computing, NUI등 다양한 분야의 접목과 응용을 통해 최적의 IT 인프라 구축을 위해서 노력하고 있다.
Email: iwinkey@hotmail.com
Blog: http://winkey.tistory.com

 

  이번에 설명 해 드릴 내용은 매우 짧은 내용입니다. ViewBox 는 자기 자신 위에 다른 컨트롤을 올려 놓을 수 있는 일종의 컨테이너 역할을 하는 레이아웃과 관련된 컨트롤입니다. 한 가지 특이한 점은 ViewBox는 자기 자신의 크기가 바뀔 때 자기 위에 있는 컨트롤의 크기도 함께 변화시키는 특징이 있습니다.

그래서 크기를 자연스럽게 변화시키거나 할 때 유용하게 사용할 수 있는 컨트롤입니다.

 

<그림1> ViewBox 샘플

 

ViewBox를 사용할 경우에 잘 지정해야 하는 속성이 두 가지가 있는데 StretchDirection과 Stretch 입니다.

StretchDirection의 경우 크기가 변화 될 때 어느 정도까지 변화되는가에 대한 상한 혹은 하한선을 결정할 때 사용하는 속성인데 여기에서 설정할 수 있는 옵션은 다음과 같습니다.

 

UpOnly : 내용이 부모보다 작은 경우에만 크기가 커집니다. 내용이 부모보다 크면 크기가 줄어들지 않습니다.

DownOnly : 내용이 부모보다 큰 경우에만 크기가 줄어듭니다. 내용이 부모보다 작으면 크기가 커지지 않습니다.

Both : Stretch 모드에 따라 내용이 부모에 맞게 늘어납니다.

 

또 Stretch 속성은 ViewBox안에 있는 컨트롤이 ViewBox내에 채워지는 형태를 지정할 수 있게 되었는데 아래와 같이 4가지 방식으로 채워 질 수 있게 되어 있습니다.

 

None : 내용의 원래 크기가 유지됩니다.

Fill : 내용의 크기가 조정되어 대상 크기를 채웁니다. 가로 세로 비율은 유지되지 않습니다.

Uniform : 원래 가로 세로 비율을 유지하면서 대상 크기에 맞게 콘텐츠의 크기가 조정됩니다.

UniformToFill : 원래 가로 세로 비율을 유지하면서 대상 크기를 채우도록 콘텐츠의 크기가 조정됩니다. 대상 사각형의 가로 세로 비율이 소스와 다른 경우에는 소스 내용이 대상 크기에 맞게 클리핑됩니다.

 

여러 TileBrush Stretch 설정

<그림2>Stretch의 4가지 형태

 

첨부된 파일을 실행시켜서 여러 가지 옵션을 잘 실행시켜 보시기 바랍니다.

신고
2010.01.25 09:00

1.RichTextArea Part 1
2.RichTextArea Part 2
3.Accessing Web Camera and Microphone
4.Right Click Mouse Events

5.MouseWheel API

6.Using Silverlight Controls As Drip Targets
7.DataGrid Enhancements
8.Printing API Basics 
9.Hosting HTML Content
10.Accessing the Global Clipboard Programmatically 
11.Using the ViewBox Control 
12.Asynchronous Data Validation 
13.BiDi and Right-to-Left Support 
14.Notification API
15.Local File Access 
16.RIA Services support in Visual Studio 2010 

블로그 이미지 김영욱 차장 Microsoft Korea  .NET Evangelist
Enterprise UX 를 위한  UI 기술과 SOA, Cloud Computing, NUI등 다양한 분야의 접목과 응용을 통해 최적의 IT 인프라 구축을 위해서 노력하고 있다.
Email: iwinkey@hotmail.com
Blog: http://winkey.tistory.com

 

일시적으로 어떤 데이터를 잠시 보관해 두는 영역을 클립보드라고 부릅니다. 사용자의 의지에 따라서 다른 곳의 내용을 복사해서 붙여 넣기 등의 작업을 할 때 임시로 보관해 두는 메모리 영역도 역시 클립보드 입니다.

 

사용자의 의지라고 제가 명시한 이유는 클립보드의 내용을 접근할 때 일반적으로는 사용자들이 Ctrl + C, V 등을 사용해서 클립보드의 작업을 하지만 그렇지 않은 경우도 있을 수 있기 때문입니다. 우리가 만들려고 하는 응용프로그램에서 클립보드의 내용에 직접 접근해야 할  필요가 있을 수도 있습니다.

 

Silverlight 3까지는 코드 상에서 클립보드에 접근할 수 있는 방법을 제공해 주지 않고 있었지만 Silverlight 4에서는 방법을 제공하고 있습니다.

 

<그림1>클립보드 샘플 프로그램

 

<그림1>에 나오는 샘플에서 첫 번째 RichTextArea 안에 포함되어 있는 내용을 Ctrl + C를 통해서 Copy 하고 두 번째 RichTextArea에 Ctrl + V를 통해서 붙여 넣기 했을 경우에는 아무런 메시지 없이 잘 실행됩니다.

하지만  하단에 있는 Copy 혹은 Paste를 사용할 경우 다음과 같은 경고 메시지가 나타나게 됩니다.

 

<그림2> 클립보드 접근시 나오는 메시지

 

이렇게 코드에서 클립보드에 접근할 경우에 메시지가 뜨는 이유는 클립보드 역시 로컬의 자원이기 때문에 보안 모델을 위반할 수 있기 때문에 사용자에게 적절하게 메세지를 주는 것 입니다.

 

클립보드에 실제로 접근하기 위해서 사용할 수 있는 객체는 System.Windows.Clipboard 입니다.

클립보드에  선택된 텍스트를 저장하기 위해서는

 

Clipboard.SetText( LeftTextBox.Selection.Text );

와 같이 사용할 수 있으며 반대로 클립보드에 있는 내용을 가져오기 위해서는

 

RightTextBox.Selection.Text = Clipboard.GetText();

와 같이 사용할 수 있습니다.

 

여기서 한 가지 더 알아두면 좋은 메소드는 현재 클립보드에 내용이 있는지 없는지 확인하는 Clipboard.ContainsText() 입니다. Clipboard.ContainsText()의 경우 내용 유무를 bool 형태로 돌려주게 되어 있습니다.

신고
2010.01.21 12:00

1.RichTextArea Part 1
2.RichTextArea Part 2
3.Accessing Web Camera and Microphone
4.Right Click Mouse Events
5.MouseWheel API
6.Using Silverlight Controls As Drop Targets
7.DataGrid Enhancements
8.Printing API Basics
9.Hosting HTML Content
10.Accessing the Global Clipboard Programmatically 
11.Using the ViewBox Control 
12.Asynchronous Data Validation 
13.BiDi and Right-to-Left Support 
14.Notification API
15.Local File Access 
16.RIA Services support in Visual Studio 2010 

블로그 이미지 김영욱 차장 Microsoft Korea  .NET Evangelist
Enterprise UX 를 위한  UI 기술과 SOA, Cloud Computing, NUI등 다양한 분야의 접목과 응용을 통해 최적의 IT 인프라 구축을 위해서 노력하고 있다.
Email: iwinkey@hotmail.com
Blog: http://winkey.tistory.com

 

 
<그림1> Web browser 컨트롤을 사용해서 RSS를 읽어 들인 예

HTML을 Silverlight에서 바로 보여줄 수 있다면…. 할 수 있는 게 엄청 많아 질 것입니다. Silverlight 4 부터는 HTML을 Silverlight에서 바로 보여줄 수 있는 컨트롤이 추가 되어서 Silverlight에서 할 수 있는 게 엄청 많아 졌습니다.

HTML을 불러올 수 있는 방법은 html 파일을 직접 읽어오는 방법 혹은 html 문자열을 이해하는 방법 그리고 타 사이트에 있는 HTML을 직접 읽어오는 방법 등 여러 가지 방법이 있을 수 있는데 HTML 컨트롤의 치명적인 한 가지 제약 사항이 있습니다. 그것은 바로 OOB(Out of browser) 상태에서만 지원되는 점입니다.

 

웹 브라우저 컨트롤을 사용하기 위해서는 다음과 같이 한 줄만 입력하면 됩니다.


 <WebBrowser x:Name="HtmlContent" Height="600" Width="800” />


 하지만 웹 브라우저 컨트롤은 기본적으로 OOB에서만 실행되기 때문에 다음과 같은 코드를 사용해서 OOB 상태에서만 실행되는 것을 확인해야 합니다.


 if (!App.Current.IsRunningOutOfBrowser)
{
    WarningText.Visibility = Visibility.Visible;
}


 두 번째로 현재 실행되고 있는 Silverlight 애플리케이션이 이미 해당 컴퓨터의 로컬에 설치되었는지를 확인하고 설치가 되지 않았으면 설치 버튼을 노출 시켜주기 위해서 다음과 같은 코드가 필요합니다.


 if (App.Current.InstallState == InstallState.Installed)
{
    InstallButton.Visibility = Visibility.Collapsed;
}
else
{
    return;
}


 위의 두 가지 소스에서 보면 알 수 있지만 App 객체는 현재 실행되고 있는 애플리케이션의 정보를 알 수 있게 해준다.
그럼 해당 컴퓨터에서 자기 자신을 설치하기 위한 코드는 어떤 것일까? 놀랍게도 딱 한 줄만 사용하면 됩니다.


 App.Current.Install();


 Web Browser 컨트롤에서 특정한 페이지로 이동하기 위해서는 다음과 같이 Navigate 메소드를 사용하면 됩니다.


 HtmlContent.Navigate(new Uri(“http://winkey.tistory.com”));


 하지만 Silverlight는 좀 더 재미있는 방법도 제공되고 있는데 로컬에 있는 HTML 파일을 읽어드릴 수도 있습니다. 이럴 경우에는 아래와 같은 방법으로 접근 할 수 있습니다.


 HtmlContent.Navigate(new Uri(App.Current.Host.Source, “./test.html”));


재미있는 사실은 Web Browser 컨트롤에서는 그냥 메모리상에서 문자열로 조합되어 있는 html도 역시 출력할 수 있습니다.


HtmlContent.NavigateToString(“<P>Hello World<P>”);


이럴 경우에는 Navigate 메소드가 아니라 NavigateToString을 사용하셔야 합니다.

 
<그림2> NavigateToString을 사용해서 HTML 문자열을 읽어드린 경우.


이미 이 글을 읽으시는 분들의 머리 속에는 이것을 활용할 아이디어가 무궁무진하게 흘러 나오기 시작하는 느낌이 들 것입니다. 첨부된 샘플을 보시면 XML 타입으로 되어 있는 RSS를 파싱하는 방법도 함께 포함되어 있으니 꼭 참조하시기 바랍니다.

신고
2010.01.20 09:00

1.RichTextArea Part 1
2.RichTextArea Part 2
3.Accessing Web Camera and Microphone
4.Right Click Mouse Events
5.MouseWheel API
6.Using Silverlight Controls As Drop Targets
7.DataGrid Enhancements
8.Printing API Basics
9.Hosting HTML Content
10.Accessing the Global Clipboard Programmatically 
11.Using the ViewBox Control 
12.Asynchronous Data Validation 
13.BiDi and Right-to-Left Support 
14.Notification API
15.Local File Access 
16.RIA Services support in Visual Studio 2010 

블로그 이미지 김영욱 차장 Microsoft Korea  .NET Evangelist
Enterprise UX 를 위한  UI 기술과 SOA, Cloud Computing, NUI등 다양한 분야의 접목과 응용을 통해 최적의 IT 인프라 구축을 위해서 노력하고 있다.
Email: iwinkey@hotmail.com
Blog: http://winkey.tistory.com

 

웹에서 프린트를 마음 것 할 수 있다면 어떨까? 여러 가지로 편리한 점 들이 많이 있을 것이다. 일반적인 웹 페이지의 경우 레이아웃 자체가 가변적이기 때문에 기본적으로 정해져 있는 모양대로 프린트 되지 못합니다. 그래서 미리 보기를 적절히 사용해 가면서 결과물을 미리 확인하지 않았다가는 엄청난 양의 종이를 낭비하게 됩니다.

 

Silverlight 4에서는 드디어 프린트 기능이 지원됩니다. 시스템에 설치되어 있는 프린트의 목록을 가져오고 가져온 목록을 기반으로 해서 프린트를 선택해서 프린트 할 수 있습니다.

 

<그림1> 프린트 기능을 보여주는 샘플 프로그램

 

프린트 기능을 사용하는 방법은 의외로 심플합니다. 프린트를 사용하는 방법은
System.Windows.Printing.PrintDocument 클래스를 사용하면 됩니다.

 

PrintDocument docToPrint = new PrintDocument();
docToPrint.DocumentName = "Entire Screen Sample";

 

docToPrint.PrintPage += (s, args) =>
    {
        args.PageVisual = this.StackOfStuff;
    };

 

docToPrint.Print();

<소스1>프린트 기능의 사용 예

 

ProntDoucment 클래스의 PrintPage에서 PageVisual 속성에 출력하려고 하는 객체를 지정하고 Print( );를 호출하는 것으로 바로 프린트가 이루어 집니다.

 

<그림2>프린터 선택 화면

 

약간의 기교를 부린다면 프린팅을 시작할 때 혹은 프린팅이 종료 되었을 때 무언가 사용자에게 보여주는 방식으로 코딩하고 싶으면 다음과 같이 StartPrint와 EndPrint 두 개를 잘 활용 할 수 있습니다.

 

PrintDocument docToPrint = new PrintDocument();
docToPrint.DocumentName = "Entire Screen Sample";

docToPrint.StartPrint += (s, args) =>
    {
        ActivityDisplay.IsActive = true;
    };

docToPrint.PrintPage += (s, args) =>
    {
        args.PageVisual = this.StackOfStuff;
    };

docToPrint.EndPrint += (s, args) =>
    {
        ActivityDisplay.IsActive = false;
    };

docToPrint.Print();

<소스2> 시작과 종료를 활용하는 예

 

이외에도 동적으로 객체들을 쌓아서 출력하는 방식도 사용할 수 있는데 이는 첨부된 샘플을 잘 살펴보시면 될 것 같습니다.

신고
2010.01.18 09:00

71.RichTextArea Part 1
2.RichTextArea Part 2
3.Accessing Web Camera and Microphone
4.Right Click Mouse Events
5.MouseWheel API
6.Using Silverlight Controls As Drop Targets
7.DataGrid Enhancements
8.Printing API Basics 
9.Hosting HTML Content
10.Accessing the Global Clipboard Programmatically 
11.Using the ViewBox Control 
12.Asynchronous Data Validation 
13.BiDi and Right-to-Left Support 
14.Notification API
15.Local File Access 
16.RIA Services support in Visual Studio 2010  

블로그 이미지 김영욱 차장 Microsoft Korea  .NET Evangelist
Enterprise UX 를 위한  UI 기술과 SOA, Cloud Computing, NUI등 다양한 분야의 접목과 응용을 통해 최적의 IT 인프라 구축을 위해서 노력하고 있다.
Email: iwinkey@hotmail.com
Blog: http://winkey.tistory.com

 

국내에서 뿐만 아니라 전 세계적으로 많은 데이터를 보여주기 위해서 가장 많이 사용되는 방법은 바로 DataGrid 일 것입니다. Silverlight에서는 기본적으로 DataGrid를 제공하고 있으며 또 상용 컴퍼넌트도 종류가 아주 많이 있습니다.

Silverlight 4에서는 기본 DataGrid도 개선 사항이 있다고 합니다.

 

<그림1> Sample Program

 

Silverlight 4에서는 DataGrid가 좀 더 Windows용 응용 프로그램에 가까워 졌습니다. 앞서서 설명했던 마우스 오른쪽 버튼의 사용이나 마우스 휠 버튼의 사용등과 마찬가지로 DataGrid 역시 기존에는 그냥 데이터를 뿌려주는 것에 불과 했던 것에서 Windows 용 응용 프로그램에서 사용했던 경험을 그대로 활용할 수 있는 방향으로 바뀌었습니다.

 

image

<그림2>DataGrid 컬럼의 설정

 

<그림2>에서 보는 바와 같이 컬럼의 폭을 설정 할 수 있는 방법이 많아 졌습니다. 자동으로 설정되는 Auto, 고정된 폭을 가지고 있는 Pixel, 그리고 나머지 공간을 균등하게 가져가는 Star 마지막으로 Cell이나 Header를 기준으로 설정하는 SizeToCells, SizeTOHeader 등이 있습니다.

 

  1. <data:DataGrid AutoGenerateColumns="False">
  2. <data:DataGrid.Columns>
  3. <data:DataGridTextColumn Header="One" Width="Auto" />
  4. <data:DataGridTextColumn Header="Two" Width="*" />
  5. <data:DataGridTextColumn Header="Three" Width="3*" />
  6. </data:DataGrid.Columns>
  7. </data:DataGrid>

<소스1>DataGrid의 활용 예

<소스1>에서 보면 3~5번 줄에서와 같이 세 개의 컬럼이 추가 되어 있는데 Auto, Star, 등을 지정하고 있습니다.

 

image

<그림3>가변 컬럼의 변화

 

<그림3>의 결과를 보면 25%, 75%사이즈를 가지고 있는 것을 볼 수 있습니다. 또 하나 재미있는 점은 클립보드를 사용할 수 있게 된 점이라고 할 수 있습니다. 클립보드를 사용할 수 있게 되어서

image image image

<그림4>클립보드의 활용

 

<그림4>처럼 DataGrid의 내용을 엑셀에 붙여넣는 것과 같은 작업이 가능하게 되었습니다.

마지막으로 FlowDirectionText 속성을 사용해서 글자의 흐름을 제어할 수 있는 이 기능을 통해서 아랍어와 같은 RTL(Right To Left)기반의 언어들을 지원할 수 있습니다.

새로 추가된 DataGrid의 기능을 테스트 해볼 수 있는 Sample을 첨부합니다.


Sample 소스에서 Customer.cs 파일은 데이터를 바인딩 하기 위해서 추가한 Entity Class의 역할을 합니다.  그리고  DataGridLenthUnitType.cs 는 DataGrid의 Length 옵션을 표현한 Class 입니다.

신고
2010.01.13 17:38

1.RichTextArea Part 1
2.RichTextArea Part 2
3.Accessing Web Camera and Microphone
4.Right Click Mouse Events

5.MouseWheel API
6.Using Silverlight Controls As Drop Targets
7.DataGrid Enhancements
8.Printing API Basics 
9.Hosting HTML Content
10.Accessing the Global Clipboard Programmatically 
11.Using the ViewBox Control 
12.Asynchronous Data Validation 
13.BiDi and Right-to-Left Support 
14.Notification API
15.Local File Access 
16.RIA Services support in Visual Studio 2010   

블로그 이미지 김영욱 차장 Microsoft Korea  .NET Evangelist
Enterprise UX 를 위한  UI 기술과 SOA, Cloud Computing, NUI등 다양한 분야의 접목과 응용을 통해 최적의 IT 인프라 구축을 위해서 노력하고 있다.
Email: iwinkey@hotmail.com
Blog: http://winkey.tistory.com

 

Drag and Drop 기능은 직관적인 기능을 구현할 수 있는 인터페이스 중에 하나 입니다. Silverlight에서도 Drag and Drop을 통해서 괜찮은 인터페이스를 만들 수 있도록 하는 기능이 추가 되었습니다. 물론 이전 버전에서도 안되었던 것은 아닙니다만 Silverlight 4에서는 강화된 Out of browser 기능과 맞물려서 좀 더 강력하게 사용할 수 있는 방법들이 제공되고 있습니다.

 

이번 강좌에서는 <그림1>과 같은 샘플을 만들어 볼 예정입니다. XAML파일, Image, 동영상 등을 Drop on me라는 버튼에 Drag 하게 되면 아래에 추가 되는 형태로 동작할 예정입니다.

<그림1> 완성된 샘플 프로그램

 

버튼과 같은 컨트롤에는 모두 Drop, DragEnter, EragLeave, AllowDrop와 같은 속성들이 포함되어 있습니다. 먼저 Drag and Drop 기능을 사용하기 위해서는 AllowDrop = true로 설정해서 활성화 시켜줘야 합니다.

 

ButtonDropTarget.Drop += doDrop;

ButtonDropTarget.DragEnter += doDragEnter;

ButtonDropTarget.DragLeave += doDragLeave;

ButtonDropTarget.AllowDrop = true;

ButtonDropTarget.Click += ButtonDropTargetClick;

 

이벤트에서 DragEnter는 Drag해서 해당 컨트롤 위에 왔을 경우를 의미하고 DragLeave는 들어왔다가 나갈 때 발생하는 이벤트이다. 마지막으로 Drop은 해당 객체 위에 끌고 온 것을 놨을 때(Drop) 발생하는 이벤트 입니다.

우선 DragEnter와 DragLeave 이벤트에서는 간단하게 지금 해당 컨트롤 위에 올라오거나 올라왔다가 나간 객체에 대한 정보를 리스트 박스에 보여주려고 합니다.

 

private void doDragEnter( object sender, DragEventArgs e )
{
  string senderName = GetSenderName( sender );
  listBox.Items.Add( "Drag enter by " + senderName );
}

 

private void doDragLeave( object sender, DragEventArgs e )
{
  string senderName = GetSenderName( sender );
  listBox.Items.Add( "Media drag leave by " + senderName );
}

 

두 개의 이벤트 핸들의 내용을 보면 내용이 거의 유사한 것을 볼 수 있습니다. 둘 다 senderName을 GetSenderName( )을 통해서 얻어내서 이것을 리스트 박스에 추가 하고 있습니다. GetSenderName( )은 단순히 sender의 이름을 리턴 해주는 함수로 되어 있습니다.

 

private static string GetSenderName( object sender )
{
  FrameworkElement fe = sender as FrameworkElement;
  return fe.Name;
}

 

실제 기능은 모두  doDrop 이벤트 핸들러에 포함되어 있습니다.

Drag and Drop에 관련된 이벤트 Args는 DragEventArgs로 여기에 Data라는 속성에 현재 Drag 혹은 Drop한 객체에 대한 정보가 들어 있습니다.

 

아래와 같이 dataObject를 생성해서 Data속성에 있는 값을 받을 수 있습니다.

 

IDataObject dataObject = e.Data as IDataObject;

 

추가된 것이 어떤 것인지 분명해 지면 해당 포멧에 맞추어서 각각의 동작 방식을 기술해 줍니다. xaml 파일의 경우는 해당 파일을 열어서 사용할 수 있게 되어 있고 mp4는 MediaElement를 사용해서 실행 시키는 것을 볼 수 있습니다. 또 이미지의 경우는 이미지를 열어서 볼 수 있게 되어 있습니다.

 

    if ( file.Extension.Equals( ".xaml" ) )
    {
      string contents;
      using ( Stream stream = file.OpenRead() )
      {
        using ( StreamReader reader = new StreamReader( stream ) )
        {
          contents = reader.ReadToEnd();
        }
      }
      UIElement uiElement = XamlReader.Load( contents ) as UIElement;
      this.xamlViewer.Children.Add( uiElement );
    }
    else if ( file.Extension.Equals( ".mp4" ) )
    {
      var me = new MediaElement();
      me.Width = 400;  // mp4 ratio is 4:3
      me.Height = 300;
      me.Source = new Uri( file.Name, UriKind.RelativeOrAbsolute );
      this.xamlViewer.Children.Add( me );
      me.Play();
    }
    else  // not xml and not mp4
    {
      try  // so we assume it is an image
      {
        using ( var stream = file.OpenRead() )
        {
          var imageSource = new BitmapImage();
          imageSource.SetSource( stream );
          image.Source = imageSource;
        }
      }
      catch ( Exception )
      {
        listBox.Items.Add( "Oops, " + file.Name + " is not an image file" );
      }   // end catch
    }     // end else not .xaml

실제 Drag and Drop을 구현하는 코드는 몇 줄에 불과한 것을 알 수 있습니다.
소스코드는 아래에서 다운로드 받을 수 있습니다.

Download C# Source Code

신고
2010.01.12 09:00

1.RichTextArea Part 1
2.RichTextArea Part 2
3.Accessing Web Camera and Microphone
4.Right Click Mouse Events
5.MouseWheel API

6.Using Silveright Controls As Drop Targets
7.DataGrid Enhancements
8.Printing API Basics 
9.Hosting HTML Content
10.Accessing the Global Clipboard Programmatically 
11.Using the ViewBox Control 
12.Asynchronous Data Validation 
13.BiDi and Right-to-Left Support 
14.Notification API
15.Local File Access 
16.RIA Services support in Visual Studio 2010  

블로그 이미지 김영욱 차장 Microsoft Korea  .NET Evangelist
Enterprise UX 를 위한  UI 기술과 SOA, Cloud Computing, NUI등 다양한 분야의 접목과 응용을 통해 최적의 IT 인프라 구축을 위해서 노력하고 있다.
Email: iwinkey@hotmail.com
Blog: http://winkey.tistory.com

 

일반적인 Windows 응용 프로그램들과 웹 프로그램의 가장 큰 차이점이 무엇일까요? 여러 가지 이야기를 할 수 있지만 인터페이스적인 면으로 보면 가장 큰 차이가 바로 마우스 오른쪽 버튼의 사용 여부가 가장 큰 차이점이라고 할 수 있습니다. 웹이 아닌 일반적은 응용 프로그램에서는 마우스 오른쪽 버튼을 사용해서 상황에 맞는 기능들을 호출 할 수 있지만 웹에서는 웹 브라우저에 관련된 기능들이 실행되거나 Flash나 혹은 Silverlight의 경우는 그냥 해당 런타임 정보를 보여주는 용도로만 활용되고 있는 실정입니다.

 

Silverlight 4에서는 마우스 오른쪽 버튼을 사용할 수 있게 해주었는데 그냥 마우스 오른쪽 버튼을 사용할 수 있게 되었다는 정도의 의미가 아니라 웹에서 데스크 탑 응용 프로그램의 경험을 체험할 수 있게 해 주었다는 점에서 접근하게 되면 훨씬 많은 아이디어와 좋은 방법들을 구성할 수 있을 것 같습니다.

 

서두는 이렇게 시작하지만 실제로 구현하는 방식은 아주 간단하다.

 

1. 오른쪽 마우스 버튼을 사용하기 위해서는 이벤트 핸들러를 활성화 시켜야 한다.

 

버튼과 관련된 처음 작업은 바로 이벤트 핸들러를 작성하는 것입니다.

 

ChangingRectangle.MouseRightButtonDown += new MouseButtonEventHandler(RectangleContextDown);
ChangingRectangle.MouseRightButtonUp += new MouseButtonEventHandler(RectangleContextUp);

SimpleButton.MouseRightButtonDown += new MouseButtonEventHandler(ButtonContextDown);
SimpleButton.MouseRightButtonUp += new MouseButtonEventHandler(ButtonContextUp);

 

이렇게 마우스 오른쪽 버튼의 이벤트 두 개를 모두 핸들링 합니다. 마우스와 키보드 관련 이벤트는 항상 Down, Up 이렇게 두 개가 함께 있는데 누를 때가 Down 버튼을 놓을 때가 Up 이렇게 두 가지가 함께 공존하기 때문에 그렇습니다.

마우스 오른쪽 버튼을 사용하기 위해서 주로 사용되는 방법은 Down 이벤트시에 오른쪽 마우스 버튼 이벤트를 활성화 시키는 방법입니다.

 

e.Handled = true;

 

이벤트 핸들러의 MouseButtonEventArgs 객체로 리턴되는 e의 Handled 속성을 true 로 설정하는 순간 오른쪽 마우스 버튼을 누를 때 Silverlight라는 조그만 버튼이 나타나지 않게 됩니다.

 

 

2. 팝업 메뉴를 사용하기 위해서는 팝업 메뉴를 만들어야 한다.

 

일반적인 Windows 응용 프로그램에서 오른 쪽 마우스를 사용해서 팝업 메뉴를 불러 낼 경우에는 대부분 기본으로 제공하는 메뉴 객체를 사용해서 표현하는 경우가 대부분 입니다. 하지만 Silverlight에서는 팝업과 관련된 용도로 제공하는 컨트롤은 없습니다. 기본적으로 관련된 컨트롤을 제공하지 않는 이유는 Silverlight의 높은 자유도와 관련되어 있습니다.

팝업 메뉴를 특정 형태로 제공하지 않고 원하는 디자인으로 쉽게 구성해서 사용할 수 있게 있게 해 준 것입니다.

 

팝업과 관련된 클래스를 하나 추가해야 하는데 여기서는 가장 간단한 디자인으로 구성하고 있지만 실 프로젝트에서는 디자이너의 손을 거치면 좀 더 간지나는 팝업 메뉴로 만들 수 있습니다.

 

public class ColorChangeContextMenu : Dialog
{
    Rectangle _rectangle;

    public ColorChangeContextMenu(Rectangle rectangle)
    {
        _rectangle = rectangle;
    }

    protected override void OnClickOutside()
    {
        Close();
    }

    protected override FrameworkElement GetContent()
    {
        Grid grid = new Grid() { Width = 100, Height = 115 };
        Border border = new Border() { BorderBrush = new SolidColorBrush(Colors.Black), BorderThickness = new Thickness(1), Background = new SolidColorBrush(Colors.LightGray) };
        grid.Children.Add(border);

        TextBlock red = new TextBlock() { Text = "Red", Width = 90 };
        red.MouseLeftButtonUp += new MouseButtonEventHandler(ChangeColorRed);

        TextBlock blue = new TextBlock() { Text = "Blue", Width = 90 };
        blue.MouseLeftButtonUp += new MouseButtonEventHandler(ChangeColorBlue);

        TextBlock green = new TextBlock() { Text = "Green", Width = 90 };
        green.MouseLeftButtonUp += new MouseButtonEventHandler(ChangeColorGreen);

        TextBlock yellow = new TextBlock() { Text = "Yellow", Width = 90 };
        yellow.MouseLeftButtonUp += new MouseButtonEventHandler(ChangeColorYellow);

        TextBlock cancel = new TextBlock() { Text = "Cancel Menu", Width = 90 };
        cancel.MouseLeftButtonUp += new MouseButtonEventHandler(CancelContextMenu);

        ListBox options = new ListBox();
        options.Items.Add(red);
        options.Items.Add(blue);
        options.Items.Add(green);
        options.Items.Add(yellow);
        options.Items.Add(cancel);

        grid.Children.Add(options);

        return grid;
    }

    void CancelContextMenu(object sender, MouseButtonEventArgs e)
    {
        Close();
    }

    void ChangeColorYellow(object sender, MouseButtonEventArgs e)
    {
        SolidColorBrush solidColor = new SolidColorBrush();
        solidColor.Color = Colors.Yellow;
        _rectangle.Fill = solidColor;
        Close();
    }

    void ChangeColorGreen(object sender, MouseButtonEventArgs e)
    {
        SolidColorBrush solidColor = new SolidColorBrush();
        solidColor.Color = Colors.Green;
        _rectangle.Fill = solidColor;
        Close();
    }

    void ChangeColorBlue(object sender, MouseButtonEventArgs e)
    {
        SolidColorBrush solidColor = new SolidColorBrush();
        solidColor.Color = Colors.Blue;
        _rectangle.Fill = solidColor;
        Close();
    }

    void ChangeColorRed(object sender, MouseButtonEventArgs e)
    {
        SolidColorBrush solidColor = new SolidColorBrush();
        solidColor.Color = Colors.Red;
        _rectangle.Fill = solidColor;
        Close();
    }
}

 

좀 내용이 길기는 하지만 간단한 내용입니다. ListBox 컨트롤에 TextBlock을 추가해서 버튼처럼 사용할 수 있게 하고 있습니다. 그리고 이벤트 핸들러를 걸어 놓은 형태 입니다. 처음에는 이렇게 좀 길게 소스를 써야 하겠지만 자주 사용되는 기능인 만큼 컨트롤로 잘 만들어 두면 편리하게 사용할 수 있을 것 같습니다.

 

이 클래스를 불러와서 사용하기 위해서는 아래와 같이 사용할 수 있습니다.

 

ColorChangeContextMenu contextMenu = new ColorChangeContextMenu(ChangingRectangle);
contextMenu.Show(e.GetPosition(LayoutRoot));

 

e.GetPosition( )을 사용하는 이유는 현재 마우스 위치를 파악해서 해당 되는 위치에 팝업 메뉴를 보여 주기 위해서 입니다. 여기까지 했다면 다음과 F5번을 눌러서 실행 시켜 보면 다음과 같은 결과를 볼 수 있습니다.

 



신고
2010.01.11 09:00

1.RichTextArea Part 1
2.RichTextArea Part 2
3.Accessing Web Camera and Microphone
4.Right Click Mouse Events
5.MouseWheel API

6.Using Silveright Controls As Drop Targets
7.DataGrid Enhancements
8.Printing API Basics 
9.Hosting HTML Content
10.Accessing the Global Clipboard Programmatically 
11.Using the ViewBox Control 
12.Asynchronous Data Validation 
13.BiDi and Right-to-Left Support 
14.Notification API
15.Local File Access 
16.RIA Services support in Visual Studio 2010 

 

 

블로그 이미지 김영욱 차장 Microsoft Korea  .NET Evangelist
Enterprise UX 를 위한  UI 기술과 SOA, Cloud Computing, NUI등 다양한 분야의 접목과 응용을 통해 최적의 IT 인프라 구축을 위해서 노력하고 있다.
Email: iwinkey@hotmail.com
Blog: http://winkey.tistory.com

 

Silverlight 4 에서 추가 된 기능 중에서 가장 재미있는 기능을 하나 뽑으라고 한다면 저는 주저 없이 Web Camera와 Microphone의 지원이라고 이야기 할 수 있을 만큼 Web Camera와 Microphone의 추가는 많은 가능성을 가지고 있는 기능 중에 하나 입니다. Flash에서도 이미 지원되고 있지만 효율 및 신뢰성 측면에서는 Silverlight 4가 좀 더 안정된 기능을 제공 할 수 있을 것으로 기대하고 있습니다.

 

Web Camera를 활용할 수 있는 분야라면 어떤 것이 있을 까요? 우선 화상회의 와 같은 부분들도 생각할 수 있고 또 Web Camera를 사용한 사진 촬영으로 각종 프로필 사진을 대치 한다든지 하는 용도로 요긴하게 사용할 수 있습니다. 하지만 무엇보다도 어학 및 기타 교육 관련 사이트에서 적극적으로 활용해 볼 만한 기능인 것 같습니다.

 

이번 강좌에서는 아래와 같은 기능을 완성해 볼 예정입니다.

먼저 Web Camera나 Microphone이 하나 이상 있을 수 있기 때문에 해당 되는 장치의 목록을 보여주고 원하는 장치를 선택할 수 있게 할 예정입니다. 장치를 선택하고 나서 바로 Web Camera 영상을 볼 수도 있고 스넵셧 컷도 찍을 수 있게 만들어 볼 예정입니다.

 

1. 출력은 Rectangle로 한다.

 

Silverlight 4가 Web Camera의 출력을 위해서 새로운 컨트롤을 제공하지는 않습니다. 대신 기존의 컨트롤에 출력할 수 있도록 Brush 형태로 제공할 수 있습니다. 이번 샘플에서는 사각형을 나타내는 Rechtangle 컨트롤에 출력할 예정입니다.

 

<Rectangle x:Name="WebcamCapture" Width="320" Height="240" Fill="White"/>

 

UI를 나타내는 XAML에 위와 같이 Rectangel을 하나 추가해서 여기에서 Web Camera의 출력을 보여줄 예정입니다.


2. Video & Audio 장치는 복수개가 있을 수 있다.

 

노트북을 사용하는 사용자 혹은 데스크탑을 사용한 다 하더라도 시스템에 기본 장착되어 있는 Video & Audio 장치 이외에도 추가로 다양한 장치들이 설치되어 있는 경우들이 많이 있습니다. Silverlight에서는 어떤 장치를 사용하게 될까요? 기본적인 대답은 ‘골라 쓰는 재미가 있다’ 정도 일 것입니다.

Silverlight에서는 기본적으로 해당 PC에서 설치된 장치 목록을 가져올 수 있는 System.Windows.Media.CaptionDeviceConfiguration 객체를 제공합니다. 이 객체의 주요 메소드는 다음과 같습니다.

 

GetAvailableAudioCaptureDevices( ) 시스템에 설치되어 있는 오디오 장치 목록을 가져온다.
GetAvailableVideoCaptureDevices( ) 시스템에 설치되어 있는 비디오 장치 목록을 가져온다.
GetDefaultAudioCaptureDevice( ) 시스템에서 기본 장치로 설정되어 있는 오디오 장치를 가져온다.
GetDefaultVideoCaptureDevice( ) 시스템에서 기본 장치로 설정되어 있는 비디오 장치를 가져온다.

 

화면에 해당 Video & Audio 장치 목록을 보여줄 ListBox 컨트롤을 두 개 추가해야 합니다.

 

<TextBlock Margin="5" HorizontalAlignment="Center" Foreground="White" Text="Available AUDIO Sources" Grid.Column="0" Grid.Row="0" />
<ListBox x:Name="AudioSources" Grid.Row="1" Grid.Column="0">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding FriendlyName}" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

<TextBlock Margin="5" HorizontalAlignment="Center" Foreground="White" Text="Available VIDEO Sources" Grid.Column="1" Grid.Row="0" />
<ListBox x:Name="VideoSources" Grid.Row="1" Grid.Column="1">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding FriendlyName}" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

 

두 개의 ListBox 컨트롤의 이름은 각 각 AudioSource와 VideoSourde로 지었습니다. ListBox 안에는 DataTemplate으로 바인딩 하기 좋은 형태로 구성했는데 TextBlock을 출력하는 형태로 만들었습니다. Binding FriendlyName이라고 해서 해당 장치의 FrinedlyName을 바인딩 할 수 있게 구성했습니다. FriendlyName은 이름 그대로 해당 장치 명을 의미합니다.

 

사용하는 방법은 간단해서 아래와 같이 두 개의 ListBox에 CatureDeviceConfiguratuion 객체를 사용해서 장치 목록을 가져와서 넣기만 하면 바로 바인딩 된 결과를 볼 수 있습니다.

 

// get list of audio sources
AudioSources.ItemsSource = CaptureDeviceConfiguration.GetAvailableAudioCaptureDevices();

// get list of the video sources
VideoSources.ItemsSource = CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices();

 

3. Web Camera의 내용을 출력하자.

 

장치 목록을 선택했다면 이제 화면에 Web Camera의 내용을 출력할 수 있는 준비가 거의 끝났습니다. 이제 캡쳐 버튼을 누르게 되면 호출 될 이벤트 핸들러의 내용을 채워 보도록 하겠습니다.

 

private void CaptureButton_Click(object sender, RoutedEventArgs e)
{
    if (_captureSource != null)
    {
        _captureSource.Stop(); // stop whatever device may be capturing

        // set the devices for the capture source
        _captureSource.VideoCaptureDevice = (VideoCaptureDevice)VideoSources.SelectedItem;
        _captureSource.AudioCaptureDevice = (AudioCaptureDevice)AudioSources.SelectedItem;

        // create the brush
        VideoBrush vidBrush = new VideoBrush();
        vidBrush.SetSource(_captureSource);
        WebcamCapture.Fill = vidBrush; // paint the brush on the rectangle

        // request user permission and display the capture
        if (CaptureDeviceConfiguration.AllowedDeviceAccess || CaptureDeviceConfiguration.RequestDeviceAccess())
        {
            _captureSource.Start();
        }
    }
}

 

먼저 if문에서 캡쳐 소스가 널 값인지 아닌지 먼저 체크를 합니다. 뜬금없이 _captureSoure가 나왔는데 Silverlight 4에서는 Web Camera나 혹은 Microphone의 내용을 저장할 수 있는 객체로 CaptureSoure라는 객체를 제공하고 있습니다.

여기 소스에서는 보이지 않지만

 

CaptureSource _captureSource;

 

와 같은 문장으로 해당 객체를 이미 맴버 변수로 정의해 두었습니다.

캡쳐를 시작할 때 이미 해당 객체가 캡쳐를 하고 잇으면 해당 캡쳐 장치들이 응답하지 못하기 때문에 _captureSource.Stop()을 호출해서 먼저 정지를 시킵니다.

 

아래의 두 줄은 캡쳐 할 장치를 선택할 수 있게 해주는 소스 입니다.  

_captureSource.VideoCaptureDevice = (VideoCaptureDevice)VideoSources.SelectedItem;
_captureSource.AudioCaptureDevice = (AudioCaptureDevice)AudioSources.SelectedItem;

 

위에서도 언급했지만 Web Camera를 위한 특별한 컨트롤은 제공되지 않는다고 했습니다. 대신 Brush를 사용 할 수 있다고 했는데 아래 내용은 Brush를 설정하는 부분입니다.

 

VideoBrush vidBrush = new VideoBrush();
vidBrush.SetSource(_captureSource);
WebcamCapture.Fill = vidBrush; // paint the brush on the rectangle

 

VideoBrush를 정의하고 해당 VideoBrush의 소스를 _captrueSoure로 설정하고 있습니다. 그리고 앞에서 Web Camera의 출력용으로 사용하기 위해서 미리 정의해둔 Rectangle 객체인 WebcamCaptrue의 Fill 속성에 해당 VideoBrush를 설정 합니다.

 

이제 장치들이 접근 가능하다면 _captureSource.Start()를 호출하는 것으로 Web Camera의 연결이 끝났습니다.

참 쉽죠 ^^

 

  4. 사진을 찍어 보자.

 

Web Camera를 사용해서 스냅 셧을 찍는 기능을 구현 하는 작업이 이전에는 그리 단순한 작업이 아니었지만 Silverlight 4에서는 아주 심플하게도 아래 한 줄이 해당 기능을 다 구현해 줍니다. 

 

_captureSource.AsyncCaptureImage((snapImage)

 

나머지 소스는 첨부된 샘플을 참조하시면 이해하시리라 믿고 일단 패스 합니다.

신고
2010.01.07 09:00

1.RichTextArea Part 1
2.RichTextArea Part 2
3.Accessing Web Camera and Microphone
4.Right Click Mouse Events
5.MouseWheel API

6.Using Silveright Controls As Drop Targets
7.DataGrid Enhancements
8.Printing API Basics 
9.Hosting HTML Content
10.Accessing the Global Clipboard Programmatically 
11.Using the ViewBox Control 
12.Asynchronous Data Validation 
13.BiDi and Right-to-Left Support 
14.Notification API
15.Local File Access 
16.RIA Services support in Visual Studio 2010  
 

블로그 이미지 김영욱 차장 Microsoft Korea  .NET Evangelist
Enterprise UX 를 위한  UI 기술과 SOA, Cloud Computing, NUI등 다양한 분야의 접목과 응용을 통해 최적의 IT 인프라 구축을 위해서 노력하고 있다.
Email: iwinkey@hotmail.com
Blog: http://winkey.tistory.com


RichTextArea 를 설명하는 두 번째 시간입니다. 지난 강좌에서는 RichTextArea를 활용하는 기본적인 방법을 설명했습니다. 이번 강좌에서는 조금 더 진도를 나가 보도록 하겠습니다.

아래 화면은 이번 강좌의 결과물로서 얻어지는 샘플입니다.  RichTextArea안에서 다양한 형태(크기, 폰트, 속성)을 가진 문단들이 한꺼번에 사용되었으며 원하는 부분만 선택해서 속성을 변경할 수 있게 되어 있습니다. 또 RichTextArea 안에 버튼을 삽입해서 동작 시키는 것도 가능하다는 것을 볼 수 있는 샘플입니다.

 

 

먼저 RichTextArea를 구성하는 방법에 대해서 설명해 드립니다. RichTextArea안에서 내용을 표현하기 위해서 사용하는 Paragraph을 사용해야 한다. Paragraph는 RichTextArea안의 내용을 표현하기 위해서 제공되는 객체이다.

 

<Paragraph x:Name="H1"
                       FontFamily="Georgia"
                       FontSize="36"
                       FontWeight="Bold"
                       TextAlignment="Center"
                       TextDecorations="Underline">
                <LineBreak />
                Rich Text Demonstration
                <LineBreak />
</Paragraph>

위의 내용은 H1이라고 명명된 문단에 Georgia  폰트 36pt 볼드체에 가운데 정렬과 언더라인 속성을 지정했습니다. 위의 그림에서 Rich Text Demonstration라고 표시된 헤더 부분을 나타내고 있는 문단을 Paragraph로 표현한 것입니다. 중간에 LineBreak는 이름 그대로 한 줄 내려가는 Line Break 입니다.

 

또 다른 형태로 사용되는 Paragraph 형태를 보면 다음과 같습니다.

<Paragraph x:Name="p3"
                       TextAlignment="Left"
                       FontFamily="Georgia"
                       FontSize="18">
                <Run Text="This is another paragraph. Oh look, a button: " />
                <InlineUIContainer>
                    <Button x:Name="inLineButton"
                            Background="Green"
                            Content="Change line 4!"
                            FontFamily="Georgia"
                            FontSize="14"
                            Height="30"
                            Width="Auto" />
                </InlineUIContainer>
                <LineBreak />
                You can click the button or
                <Run Text=" " />
                <Hyperlink NavigateUri="http://silverlightGeek.me"
                           TargetName="">this link</Hyperlink>
</Paragraph>

Paragraph 안에서 사용되는 Run은 문단 안에서 문장의 요소를 표현하기 위해서 사용되는 것으로 BreakLine과 같은 종류로 볼 수 있습니다. 또 재미있는 것은 InlineUIContainer 객체인데 이 객체를 통해서 각종 UI Control을 RichTextArea안에 포함시킬 수 있다. 위의 소스에서는 버튼을 삽입 한 것을 볼 수 있습니다.

마지막에 포함되어 있는 Hyperlink 객체는 링크를 표현하기 위해서 사용했습니다.

 

전체 XAML코드는 다음과 같습니다.

<UserControl x:Class="RTA.MainPage"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:doc="clr-namespace:System.Windows.Documents;assembly=System.Windows"
             mc:Ignorable="d"
             d:DesignHeight="500"
             d:DesignWidth="600">

    <Grid x:Name="LayoutRoot"
          Background="White"> 
        <Grid.RowDefinitions>
            <RowDefinition Height="1*" />
            <RowDefinition Height="5*" />
        </Grid.RowDefinitions>
        <StackPanel Name="stackPanel1"
                    HorizontalAlignment="Stretch"
                    Margin="0"
                    VerticalAlignment="Stretch"
                    Orientation="Horizontal">
            <CheckBox  Name="IsReadOnly"
                       Content="ReadOnly"
                       FontFamily="Georgia"
                       FontSize="14"
                       VerticalAlignment="Bottom"
                       HorizontalAlignment="Left"
                       Height="20"
                       Width="Auto"
                       Margin="5"
                       IsChecked="False" />
            <Button x:Name="Bold"
                    Content="Bold"
                    FontFamily="Georgia"
                    FontSize="14"
                    Margin="5"
                    VerticalAlignment="Bottom"
                    HorizontalAlignment="Left"
                    Height="Auto"
                    Width="60" />
        </StackPanel>
        <RichTextArea x:Name="rta"
                      Grid.Row="1" 
                      HorizontalAlignment="Stretch"
                      VerticalAlignment="Stretch"
                      TextWrapping="Wrap"
                      IsReadOnly="False">

            <Paragraph x:Name="H1"
                       FontFamily="Georgia"
                       FontSize="36"
                       FontWeight="Bold"
                       TextAlignment="Center"
                       TextDecorations="Underline">
                <LineBreak />
                Rich Text Demonstration
                <LineBreak />
            </Paragraph>
            <Paragraph x:Name="P1"
                       FontFamily="Georgia"
                       FontSize="14"
                       TextAlignment="Left">
                The text in this first paragraph is left aligned, Georgia 14.
            </Paragraph>
            <Paragraph x:Name="P2"
                       FontFamily="Georgia"
                       FontSize="12" 
                       TextAlignment="Right">
                <LineBreak />
                This is line one of the second paragraph (right aligned)
                <LineBreak />
                This is line two of the second paragraph
                <LineBreak />
                <Italic>
                    This is line three and it is in italic
                </Italic>
                <LineBreak />
                <Run x:Name="run1"
                     Text="This is line four and it is in a run!" />
                <LineBreak />
            </Paragraph>
            <Paragraph x:Name="p3"
                       TextAlignment="Left"
                       FontFamily="Georgia"
                       FontSize="18">
                <Run Text="This is another paragraph. Oh look, a button: " />
                <InlineUIContainer>
                    <Button x:Name="inLineButton"
                            Background="Green"
                            Content="Change line 4!"
                            FontFamily="Georgia"
                            FontSize="14"
                            Height="30"
                            Width="Auto" /> 
                </InlineUIContainer>
                <LineBreak />
                You can click the button or
                <Run Text=" " />
                <Hyperlink NavigateUri="http://silverlightGeek.me"
                           TargetName="">this link</Hyperlink>
            </Paragraph>

        </RichTextArea>
    </Grid>
</UserControl>

 

UI가 완성되었으니 C# 코드를 추가할 차례 입니다.  MainPage() 안에서 Loaded 이벤트 핸들러를 작성합니다.

public MainPage()
{
    InitializeComponent();
    Loaded += new RoutedEventHandler(MainPage_Loaded);
}

 

Loaded 이벤트 핸들러에서 UI과 관련된 초기화 작업과 추가적인 이벤트 핸들러를 작성해 봅니다.

 

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
   rta.IsReadOnly = false;
   Bold.Click += new RoutedEventHandler( Bold_Click );
   IsReadOnly.Click += new RoutedEventHandler( IsReadOnly_Click );
   inLineButton.Click += new RoutedEventHandler( inLineButton_Click );
}

 

먼저 rta.IsReadOnly = false를 통해서 RichTextArea를 쓰기 가능한 상태로 만들어 놓습니다. 그리고 Bold 속성을 추가하는 버튼과 ReadOnly 상태로 전환할 체크박스 그리고 RichTextArea 안에 추가해 두었던 버튼 등의 이벤트 핸들러를 설정합니다.

 

void inLineButton_Click( object sender, RoutedEventArgs e )
{
   run1.Text = "Whoa! I just changed this text dynamically!";
   run1.FontSize = 18;
   run1.FontWeight = FontWeights.Bold;
}

 

RichTextArea안에 추가 되어 있는 inLineButton에 대한 이벤트 핸들러에서는 Run 객체인 run1의 Text를 변경하고 FontSize와 Bold 속성을 변경할 수 있는 코드가 추가 되어 있다.

 

마지막으로 RichTextArea 안에서 선택한 영역을 Bold 속성으로 변경해 주는 기능을 추가 해 봅니다.

 

void Bold_Click( object sender, RoutedEventArgs e )
{
   if ( !string.IsNullOrEmpty( rta.Selection.Text ) )
   {
      rta.Selection.SetPropertyValue(
         TextElement.FontWeightProperty, FontWeights.Bold );
   }
}

 

string.IsNullOrEmpty( )를 사용해서 선택한 영역이 없을 경우를 먼저 체크하고 선택된 영역이 있을 경우에 Selection.SetPropertyValue( )를 사용해서 원하는 속성으로 변경하는 것을 볼 수 있습니다.

 

전체 소스는 첨부 된 소스 파일을 참조하시기 바랍니다. ^^


신고