Silverlight 4 OOB Trusted Applications Local File System  사용하기

Silverlight 4 BETA OOB Trusted Applications 그 두번째 시간 입니다. 이번 강좌는 Silverlight 4에서 추가된 Local File System  사용에 대해 알아 보도록 하겠습니다.

RIA Application 의 특징상 보안에 아주 엄격할 수 밖에 없습니다. 예를 들자면 Silverlight 나 Flash 의 크로스 도메인 정책을 허용 한다면 Dos 공격으로 남아 나는 사이트가 없을 것입니다. 또한 이번에 다룰 Local System 도 별다른 제약 없이 쓸수 있다면 우리의 PC 는 악성코드와 바이러스로 가득차 있을 것입니다. 생각만 해도 아주 끔찍한 결과죠.
하지만 이러한 제약으로 불편한점도 있습니다. 일단 덩치가 큰 Application의 경우 리소스 크기에 대한 제약이 심해집니다.  물론 Silverlight 는 SandBox 의 기능이 있기는 하지만 사용방법도 까다롭고, 기본적으로 제공하는 사이즈도 기본 1 MB/ OOB 25MB 라 충분치 않구요. 물론 용량을 늘리기 위해 사용자의 동의를 받으면 되지만 세상은 저같이 부정적인 사람도~ 많아서 쉽지는 않을 것입니다. ^^;;

제가 Remix 09 행사때 이런 질문을 받은적이 있습니다.  "왜 Silverlight  에서는 Local File System을 사용할 수 없는냐!!" 프로젝트 진행에 있어 상당히 제약이 된다는 불만을 토로 했습니다. 저는 ' Silverlight 의 보안의 특성상 Local File System 으로의 접근은 현재도 앞으로도 추가 되지 않을듯 합니다." 라고 답했습니다. 하지만 이번 Silverlight 4 에서는 이러한 생각이 틀렸다는 것을 알았습니다. ( 많은 사람들이 Local System 으로 접근을 허용하는 것음 의외 라고 생각 하셨을 겁니다.. 아니면 말구요 ^^;;)

Silverlight 4 에서는 한정적으로 Local File System 접근이 가능해졌습니다. 여기서 말하는 한정적이라는 말은아래와 같습니다.

1. 신뢰할수 있는 Application 이라는 것에 대해 사용자의 확인이 필요 합니다.
2. 접근이 가능한 폴더가 제한적 입니다. ( 내문서, 내비디오 , 내사진과 같은 맥의 경우 이와 유사한 폴더를 사용합니다.)


위와 같은 조건들을 갖추기만 하면 우리는 Silverlight 만으로도 훌륭한 Desktop Application 을 만들 수 있게 된 것이지요 !!

Silverlight 4 는 기존의 Silverlight API  와는 달리 File System 에 대한 권한을 모두 허용해 주었는데요.(물론  Trusted OOB 에서만 가능) 이는  Silverlight 3 와 4의 System.IO.File 네임 스페이스만 살펴봐도 쉽게 알 수가 있습니다.


사용자 삽입 이미지
Silverlight 4 는 인텔리 센스에 반응 하군요~ (착한것!! 요즘 Visual Studio 가 제 일의 70%는 대신 해주는것 같네요... 쩝 월급줘야 하나)


# 사용 가능한 폴더 얻기

위에서 File System 에 접근할 수 있는 폴더는 제한적이라고 설명을 하였는데요. 바로 접근 가능한 폴더정해져 있기 때문입니다. 접근 가능한 폴더는 Environment.GetFolderPath 메소드와 Environment.SpecialFolder 열거형 객체로 알 수 가 있습니다.

사용자 삽입 이미지
내 PC  의 내문서는 어디에  위치하고 있을까?

  var path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
  MessageBox.Show(path);

이렇게 간단하게 내문서의 위치를 알 수 있습니다.




#예제 File Browser 만들기

자! 이제 본격적으로 Local File System 을 사용해보도록 하겠습니다. 다음 예제는 내문서의 디렉토리와 파일들의 목록을 출력 하고 텍스트 파일을 생성해 보는 예제 입니다.


1. 프로젝트 만들기

Silverlight Application 을 만들기 위해 VisualStudio 2010 을 실행 합니다. VisualStudio 가 없다면  http://www.indreams.co.kr/blog/24 을 참고 하시면 됩니다.  실행이 되었다면 File-> New -> Project 를 선택 Silverlight  프로젝트를 생성합니다.

사용자 삽입 이미지


2. OOB 설정 하기

Local File System 을 사용하기 위해선  Trusted Applications 모드로 실행 해야 됩니다. 이를 위해 OOB 를 설정을 하겠습니다.

사용자 삽입 이미지

사용자 삽입 이미지

① OOB 를 사용하기위해 Enable running application OOB 를 체크 합니다.
② Trusted Applications 모드로 실행 하기 위해 OOB Settings 버튼  을 클릭 합니다.

사용자 삽입 이미지
Trusted Applications 모드로 실행 하기위해  Require elevated trust when running outside the browser 를 체크 합니다.  



3. XAML
MainPage.xaml 파일을 열어 아래의 코드를 작성 합니다.

<UserControl x:Class="FileBrowser.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"
    mc:Ignorable="d"
    Height="300" Width="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <!-- 파일 목록 -->
        <ListBox Width="200" HorizontalAlignment="Left" x:Name="FileListBox">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Image Source="{Binding Icon}"/>
                        <TextBlock Text="{Binding Name}"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <!-- 파일 정보 및 텍스트파일 입력폼  -->
        <StackPanel Margin="220,10,0,0" x:Name="FileInfoBox">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="파일(폴더)명: "/>
                <TextBlock Text="{Binding Name}" TextWrapping="Wrap"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="경로: "/>
                <TextBlock Text="{Binding Path}" TextWrapping="Wrap" Height="50" Width="140"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="생성: "/>
                <TextBlock Text="{Binding CreatTime}" TextWrapping="Wrap"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="수정: "/>
                <TextBlock Text="{Binding LastWriteTime}" TextWrapping="Wrap"/>
            </StackPanel>
            <StackPanel>
                <TextBlock Text="파일이름" Margin="15,20,0,0"/>
                <TextBox Width="150" Height="25" x:Name="InputFileName"/>
                <TextBlock Text="파일내용" Margin="15,20,0,0"/>
                <TextBox Width="150" Height="50" TextWrapping="Wrap" x:Name="InputFileContent"/>
                <Button Width="150" Height="30" Margin="0,10,0,0" Content="TXT 파일 만들기" x:Name="CreateButton"/>
            </StackPanel>
        </StackPanel>
        <!-- OOB 설치 버튼 -->
        <Button Content="Silverlight Application Install" x:Name="InstallButton" Visibility="Collapsed"/>
    </Grid>
</UserControl>


4. CS

MainPage.xaml.cs 파일을 열어 아래의 코드를 작성합니다.

using System;
using System.Windows;
using System.Windows.Controls;
using System.Collections.ObjectModel;
namespace FileBrowser
{
    public class FileData
    {
        public string Name { get; set; }
        public string Path { get; set; }
        public DateTime CreatTime { get; set; }
        public DateTime LastWriteTime { get; set; }
        public string Icon { get; set; }
    }
    public partial class MainPage : UserControl
    {
        ObservableCollection fileList = new ObservableCollection();
        public MainPage()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(MainPage_Loaded);
            this.InstallButton.Click += new RoutedEventHandler(InstallButton_Click);
            this.FileListBox.SelectionChanged += new SelectionChangedEventHandler(FileListBox_SelectionChanged);
            this.CreateButton.Click += new RoutedEventHandler(CreateButton_Click);
        }
        void CreateButton_Click(object sender, RoutedEventArgs e)
        {
            if (InputFileName.Text.Length <= 0)
            {
                MessageBox.Show("파일명을 입력하세요.");
                InputFileName.Focus();
            }
            else if (InputFileContent.Text.Length <= 0)
            {
                MessageBox.Show("내용을 입력하세요.");
                InputFileContent.Focus();
            }
            else
            {
                try
                {
                    // 내문서의 위치 가져오기
                    var path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                    // 텍스트 파일 스트림 얻기
                    System.IO.StreamWriter writer = System.IO.File.CreateText(string.Format(@"{0}\{1}{2}", path, InputFileName.Text, ".txt"));
                    // 입력 받은 테스트 스트림에 쓰기
                    writer.WriteLine(InputFileContent.Text);
                    writer.Close();
                    MessageBox.Show("메세지를 입력 하였습니다.");
                    fileList.Clear();
                    // 파일 목록 재갱신
                    LoadMyDocumentFiles();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }

        }

        void FileListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            FileInfoBox.DataContext = fileList[FileListBox.SelectedIndex];
            
        }
        void InstallButton_Click(object sender, RoutedEventArgs e)
        {
            App.Current.Install();
        }
        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            // OOB가 설치 되어 있는지 검사
            if (App.Current.InstallState == InstallState.NotInstalled)
            {
                this.InstallButton.Visibility = Visibility.Visible;
            }ㄴ
            else
            {
                // 현재 OOB 로 실행 중인지 검사
                if (!App.Current.IsRunningOutOfBrowser)
                {
                    this.LayoutRoot.Children.Clear();
                    TextBlock txt = new TextBlock();
                    txt.VerticalAlignment = VerticalAlignment.Center;
                    txt.HorizontalAlignment = HorizontalAlignment.Center;
                    txt.Text = "OOB에서만 실행하세요 ^^";
                    this.LayoutRoot.Children.Add(txt);
                }
                else
                {
                    FileListBox.ItemsSource = fileList;
                    LoadMyDocumentFiles();
                }
            }
        }
        void LoadMyDocumentFiles()
        {
            // 내문서 위치 얻기
            var path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            //디렉토리 목록 가져오기
            foreach(string data in System.IO.Directory.EnumerateDirectories(path))
            {
                FileData file = new FileData();
                System.IO.DirectoryInfo dirInfo = new System.IO.DirectoryInfo(data);
                file.Name = dirInfo.Name;
                
                file.Path = data;
                file.CreatTime = dirInfo.CreationTime;
                file.LastWriteTime = dirInfo.LastWriteTime;
                file.Icon = "/Image/dir.png";
                this.fileList.Add(file);
            }
            //파일목록 가져오기
            foreach (string data in System.IO.Directory.EnumerateFiles(path))
            {
                FileData file = new FileData();
                System.IO.FileInfo fileInfo = new System.IO.FileInfo(data);
                file.Name = fileInfo.Name;
                file.Path = data;
                file.CreatTime = fileInfo.CreationTime;
                file.LastWriteTime = fileInfo.LastWriteTime;
                file.Icon = "/Image/file.png";
                this.fileList.Add(file);
            }

        }

    }
}




# File Browser 실행 하기

1. OOB 설치 하기

프로젝트를 빌드 하게 되면 OOB 설치 버튼이 나오는데. 이는 현재의 PC  에 Silverlight Application 이 OOB로 설치되어 있지 않기 때문입니다. "안했으면 하면 될것을!!" 가감하게 버튼을 클릭해줍니다.

사용자 삽입 이미지

설치 버튼을 누르게 되면 아래와 같은 화면이 나오게 되는데 현재의 Silverlight Application 이 사용자의 컴퓨터를 접근할수 있다는 경고를 3초간 보여주게 됩니다. 3초가 지난후 에는 Install 버튼이 활성화 되는데 이때 Install 버튼을 쿨하게 눌러줍니다 !!

사용자 삽입 이미지

설치가 끝나면 우리 그토록 갈망하던 내문서의 파일들이 출력 되는것을 확인 할수 있습니다.

사용자 삽입 이미지

파일 목록을 선택하면 파일의 경로와 파일의 생성 날짜, 수정 날짜를 확인 할수 있습니다.


사용자 삽입 이미지

내문서의 TXT 파일을 생성해 봅니다. 생성할 파일명과 파일 내용을 작성하고 파일 만들기 버튼을 클릭 합니다.
 

사용자 삽입 이미지

만들어진 파일은 오른쪽의 파일 목록에서 확인 할 수 있습니다.

사용자 삽입 이미지

자 그럼 진짜 내문서에 파일이 생성 되었는지 확인해 보도록 하겠습니다.  

사용자 삽입 이미지





지금까지 Silverlight 4 를 이용해 Local File System 을 사용해 보았습니다. 참 쉽죠잉??


[샘플 페이지]
[샘플 소스 다운로드]

[Silverlight 4  Developer Runtime]

2009/11/21 11:29 2009/11/21 11:29

2009/12/28 20:21 2009/12/28 20:21
inde 이 작성.

안녕하세요. 인디 입니다.


이번 강좌는 Silverlight 4부터 추가된 OOB Trusted Applications 입니다. OOB(Out Of Browser) 는 Silverlight 3 부터 추가된 기능중에 하나인데 Silverlight 를 브라우져가 아닌 Application 형태로 실행 시킬수 있는 아주 중요한 기능중에 하나 입니다.  하지만 Silverilght 3 에서의 OOB 는 Silverlight 의 까다로운 보안 정책이 적용되면서 아쉬움이 많았는데요. 이번 Silverlight 4 는 이런까다로운 보안 정책에서 탈피해 자유로운 Application 를 구현할수 있도록 되었습니다.


Silverlight 4 OOB

1. 크로스 도메인 허용

2. Local File System 허용

3. 전체화면 모든 키보드 허용

4. 알림창 제공

5. HTML Brush제공

6. 윈도우 창 설정 제공

7.  COM 상호 운영



Trusted Applications 설정

Trusted Applications 를 사용 하기 위해서 OOB  의 설절 항목에서 다음과 같이 설정 해야 합니다.

 

사용자 삽입 이미지

이와 같이 설정된 OOB를 설치 할때는 다음과 같은 창이 보입니다.

 

사용자 삽입 이미지
설치할 Silverlight Application 이 사용자의 Local 자원으로 접근을 할수 있다는 경고를 보여 주네요.

 

 

크로스 도메인 허용

Silverlight 는 원칙적으로는 크로스 도메인을 허용하지 않지만 정책파일 (clientaccesspolicy.xml ) 을 이용하여 크로스 도메인 접근 허용지원 해주고 있습니다. 하지만 대부분의 웹사이트가 이를 지원해주고 있지않아 사용을 할수 없는 실정입니다.

 

Silverlight 4에서는 이러한 크로스 도메인 문제를 OOB 에서는 제한 없이 사용이 가능하도록 하였습니다.

 

 

Twitter API 가져오기 예제

 

[XAML]

<UserControl x:Class="TwitterEx.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"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <ListBox Margin="10,10,10,44" x:Name="StatusList">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <StackPanel Orientation="Horizontal">
                            <Image Width="50" Height="50" Source="{Binding ProfileImage}"/>
                            <TextBlock Text="{Binding Message}"/>
                        </StackPanel>
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <Button Width="280" Height="30" VerticalAlignment="Bottom" Margin="8" x:Name="GetButton" Content="Get"/>
        <Button Content="Install Silverlight Application" x:Name="InstallButton" Visibility="Collapsed"/>
    </Grid>
</UserControl>

 

[CS]

using System;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Xml.Linq;
using System.Collections.ObjectModel;
namespace TwitterEx
{
    public class TwitData
    {
        public string ProfileImage { get; set; }
        public string Message { get; set; }
    }
    public partial class MainPage : UserControl
    {
        ObservableCollection<TwitData> tweetList = new ObservableCollection<TwitData>();
        public MainPage()
        {
            InitializeComponent();
            GetButton.Click += new RoutedEventHandler(GetButton_Click);
            Loaded += new RoutedEventHandler(MainPage_Loaded);
            InstallButton.Click += new RoutedEventHandler(InstallButton_Click);
        }

        void InstallButton_Click(object sender, RoutedEventArgs e)
        {
            bool isIntall=App.Current.Install();
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            if (App.Current.InstallState == InstallState.NotInstalled)
            {
                InstallButton.Visibility = Visibility.Visible;
            }
            else
            {
                StatusList.ItemsSource = tweetList;
            }
        }

        void GetButton_Click(object sender, RoutedEventArgs e)
        {
            if (!App.Current.IsRunningOutOfBrowser)
            {
                MessageBox.Show("OOB 로 실행해 주세요.");
            }
            else
            {
                WebClient wc = new WebClient();
               
                wc.DownloadStringAsync(new Uri("http://twitter.com/statuses/user_timeline/86871375.xml"));
                wc.DownloadStringCompleted += (object _sender, DownloadStringCompletedEventArgs _e) =>
                    {
                       
                        XDocument xmldata = XDocument.Parse(_e.Result);
                        var datalist = from data in xmldata.Descendants("status")
                                       select new TwitData
                                       {
                                           Message=(string)data.Element("text"),
                                            ProfileImage=(string)data.Element("user").Element("profile_image_url")
                                       };
                        foreach (TwitData data in datalist)
                        {
                            tweetList.Add(data);
                        }
                    };
            }
        }
    }
}

 

 

[Silverlight]

 

사용자 삽입 이미지




[샘플페이지]

[샘플소스]

[Silverlight 4  Developer Runtime]



2009/12/07 09:26 2009/12/07 09:26
inde 이 작성.

안녕하세요. 어제부터 설레이고 있는 인디 입니다.


개발환경 꾸미기, WebCam 사용법 에 이어 Silverlight 4에서 추가된 MouseRightButton 이벤트로 Context Menu를 만들어

보겠습니다. 지금까지 Silverlight 는 마우스 오른쪽 버튼 이벤트를 공식적으로 지원하지 않아 JavaScript Call 같은 방법으로 그사용을 대체 하고 있었습니다.. 꼭 화장실을 갔는데.. 개운하지 않는.. 그럼 느낌이었죠. 플래시도 되는데 Silverlight 가 왜 안돼!!

하지만 이번 Silverlight4 가 나오면서 MouseRight Button 이벤트가 공식 지원 되었습니다.


우선 System.Windows.UIElement 를 살펴 보면 여러가지 추가된 것들이 보이는데요 . 그중에 Drop & Drag 관련 이벤트가 추가 된것도 보이구요(나중에 다루도록 하겠습니다.) . 이번에 다룰 이벤트 들도 추가된 것을 볼수 있습니다.


사용자 삽입 이미지


자! 추가된 부분을 확인하고 바로 사용해 보도록 하겠습니다. ^^


        public MainPage()
        {
            InitializeComponent();
            this.MouseRightButtonDown += new MouseButtonEventHandler(MainPage_MouseRightButtonDown);
            this.MouseRightButtonUp += new MouseButtonEventHandler(MainPage_MouseRightButtonUp);
        }

        void MainPage_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
        {
            MessageBox.Show("Down!");
        }

        void MainPage_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            MessageBox.Show("Up!");
        }





사용자 삽입 이미지
사용자 삽입 이미지
















잘 동작 하네요 !!  잘 동작 하는걸 확인했으니 이제 본격적으로 Context Menu  를 만들어 보겠습니다.


샘플소스는 다음과 같습니다. 4개의 Rectangle 을 생성하고 Rectangle Fill 값을 Context Menu를 통해 바꿔 보도록 하겠습니다.


[XAML]

<UserControl x:Class="SilverlightApplication2.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"
    mc:Ignorable="d"
   >

    <Grid x:Name="LayoutRoot" Background="White" Height="300" Width="400" VerticalAlignment="Center" HorizontalAlignment="Center">
       
        <Rectangle Fill="Red" Width="100" Height="100" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="30" x:Name="Rec1"></Rectangle>
        <Rectangle Fill="Blue" Width="100" Height="100" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="30" x:Name="Rec2"></Rectangle>
        <Rectangle Fill="Green" Width="100" Height="100" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="30" x:Name="Rec3"></Rectangle>
        <Rectangle Fill="Yellow" Width="100" Height="100" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="30" x:Name="Rec4"></Rectangle>
       
        <ListBox Width="100" Height="92" x:Name="ContextMenu" VerticalAlignment="Top" HorizontalAlignment="Left" Visibility="Collapsed">
            <ListBox.Effect>
                <DropShadowEffect BlurRadius="8" ShadowDepth="3" Opacity="0.3"/>
            </ListBox.Effect>
            <ListBox.RenderTransform>
                <TransformGroup>
                    <TranslateTransform x:Name="ContextMenuPosition"/>
                </TransformGroup>
            </ListBox.RenderTransform>
            <ListBox.Items>
                <ListBoxItem Content="Red Color" Background="Red"/>
                <ListBoxItem Content="Blue Color" Background="Blue"/>
                <ListBoxItem Content="Green Color" Background="Green"/>
                <ListBoxItem Content="Yellow Color" Background="Yellow"/>
            </ListBox.Items>
        </ListBox>


    </Grid>
</UserControl>

[CS]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SilverlightApplication2
{
   
    public partial class MainPage : UserControl
    {
        Rectangle selectRec=new Rectangle();   
        public MainPage()
        {
            InitializeComponent();

            //MouseRightButtonUp 이벤트 에 Context Menu가 나타나도록 하겠습니다.
            this.Rec1.MouseRightButtonUp += new MouseButtonEventHandler(RecMouseRightButtonDown);
            this.Rec2.MouseRightButtonUp += new MouseButtonEventHandler(RecMouseRightButtonDown);
            this.Rec3.MouseRightButtonUp += new MouseButtonEventHandler(RecMouseRightButtonDown);
            this.Rec4.MouseRightButtonUp += new MouseButtonEventHandler(RecMouseRightButtonDown);

            // Silverlight Runtime  Context Menu가 MouseRightButtonDown  이벤트에서 나타나므로 MouseRightButtonDown

            // 이벤트를 무효화 시킵니다.
            this.Rec1.MouseRightButtonDown += (object sender, MouseButtonEventArgs e) => e.Handled = true;
            this.Rec2.MouseRightButtonDown += (object sender, MouseButtonEventArgs e) => e.Handled = true;
            this.Rec3.MouseRightButtonDown += (object sender, MouseButtonEventArgs e) => e.Handled = true;
            this.Rec4.MouseRightButtonDown += (object sender, MouseButtonEventArgs e) => e.Handled = true;
            this.ContextMenu.SelectionChanged += new SelectionChangedEventHandler(ContextMenu_SelectionChanged);
            this.MouseLeftButtonDown += (object sender, MouseButtonEventArgs e) =>
            {
                if (ContextMenu.Visibility == Visibility.Visible)
                {
                    ContextMenu.Visibility = Visibility.Collapsed;
                }
            };
        }
        void ContextMenu_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            selectRec.Fill = (ContextMenu.SelectedItem as ListBoxItem).Background;
            ContextMenu.Visibility=Visibility.Collapsed;
        }
        void RecMouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            selectRec = (sender as Rectangle);
            ContextMenuPosition.X = e.GetPosition(LayoutRoot).X;
            ContextMenuPosition.Y = e.GetPosition(LayoutRoot).Y;
            ContextMenu.Visibility = Visibility.Visible;
        
           
        }
    }
}


[실행화면]

사용자 삽입 이미지

자!!  빨강, 파랑, 초록, 노랑 4개의 Recangle 이 생성 되었습니다. Recangle 에만 이벤트를 걸었으므로


사용자 삽입 이미지

Recangle 밖에서는 Silverlight Runtime ContextMenu 가 나오는것을 볼수 있습니다.  그럼 Context Menu 를 통해

Rectangle 의 색을 변경 하도록 하겠습니다.



사용자 삽입 이미지

파란색 Rectangle 을 노랑색으로 변경 합니다.


사용자 삽입 이미지

노랑색으로 변경된 모습을 볼수 있습니다.




지금 까지 기존의 뻘짓(?) 에서 벗어 날수 있는  MouseRightButton Event 였습니다.



[샘플페이지]

[샘플소스]

[Silverlight 4  Developer Runtime]

2009/12/07 09:25 2009/12/07 09:25
inde 이 작성.

[Silverlight 4 맛보기] #2 Silverlight 4 BETA WebCam 사용하기

안녕하세요. 인디 입니다.

오늘 Silverlight 4 소식에 하루종일 들떠 있는 인디 입니다. 앞서 개발환경에 이은 Silverlight 4 웹캠 사용하기 입니다.

Silverlight 4 beta 소식이 들렸을때 웹캠 및 마이크가 지원이 될거라는 소식에 굉장히 기뻐 했던 1인 으로서

Silverlight 4를 보자마자 가장 먼저 웹캠을 테스트 해보았습니다. 사용법도 아주 간단합니다.

System.Windows.Media 네임스페이에 CaptureSource 클래스가 추가 된것 이 보입니다.

네! 바로 이놈이 웹캠과 마이크를 담당 하는 놈입니다.

System.Windows.Media.CaptureSource 클래스는 사용자의 PC 의 캠 및 마이크 디바이스를 실버라이트로 전송해주는 역할을 합니다.

이렇게 전송된 비디오 데이터는 VideoBrush 형식으로 전달되게 됩니다.

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace CamTest
{
    public partial class MainPage : UserControl
    {
        CaptureSource camSource;    <- 바로 이놈이 디바이스를 컨트롤 할수 있는 놈입니다.
        public MainPage()
        {
            InitializeComponent();
           
            this.SnapButton.Click += new RoutedEventHandler(SnapButtonClick);
            this.StartButton.Click += new RoutedEventHandler(StartButtonClick);

            this.StopButton.Click += new RoutedEventHandler(StopButtonClick);
        }

        void StopButtonClick(object sender, RoutedEventArgs e)
        {

            if (this.camSource != null)
            {

                this.camSource.Stop();

            }

         }

        void StartButtonClick(object sender, RoutedEventArgs e)
        {
           
              CaptureDeviceConfiguration 클래스를 통해 현재 지원 가능한 디바이스를 찾습니다. 여러개의 디바이스가 있으면

              CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices() 함수를 통해 디바이스의 목록을 Collection 형으로

              받을 수 있습니다.
            if (CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices().Count == 0)
            {
                MessageBox.Show("지원하는 디바이스가 없습니다.");
            }
            else
            {
                this.camSource = new CaptureSource();
                this.camSource.VideoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();

                CaptureDeviceConfiguration 클래스의 GetDefaultVideoCaptureDevice() 함수로 기본으로 되어 있는 디바이스를

                찾을수 있습니다.

                this.Cam.SetSource(this.camSource);      CaptureSource 를 VideoBrush의 Source로 연결 시킵니다.
                if (this.camSource != null)
                {
                    this.camSource.Stop();
                    if (CaptureDeviceConfiguration.AllowedDeviceAccess || CaptureDeviceConfiguration.RequestDeviceAccess())
                        CaptureDeviceConfiguration 클래스로 디바이스로 접근이 가능한지 , 디바이스 자원을 접근하겠다는 사용자

                        동의 값을 얻을수 있습니다.

                {
                        this.camSource.Start();   디바이스 자원을 활성화 합니다.
                    }
                }
            }
        }
        void SnapButtonClick(object sender, RoutedEventArgs e)
        {
            WriteableBitmap bitmap = new WriteableBitmap(this.CamBox, null);
            Image img = new Image();
            img.Width = 50;
            img.Height = 35;
            img.Source = bitmap;
            SnapList.Items.Add(img);
        }
    }
}

[XAML]

<UserControl x:Class="CamTest.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"
    mc:Ignorable="d"
    Height="300" Width="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <Rectangle Margin="20,20,100,100" Fill="Black"/>
        <Rectangle Margin="20,20,100,100" x:Name="CamBox">
            <Rectangle.Fill>
                <VideoBrush x:Name="Cam"/>
            </Rectangle.Fill>
        </Rectangle>
        <ListBox Width="90" Height="180" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,20,6,0" x:Name="SnapList"/>
        <StackPanel VerticalAlignment="Bottom" Margin="0,0,0,30" Orientation="Horizontal" HorizontalAlignment="Center">
            <Button Content="Start" Width="100" Height="30" Margin="3" x:Name="StartButton"/>
            <Button Content="Stop" Width="100" Height="30" Margin="3" x:Name="StopButton"/>
            <Button Content="Snap Shot" Width="100" Height="30" Margin="3" x:Name="SnapButton"/>
        </StackPanel>
    </Grid>
</UserControl>




 

[실행화면]

사용자 삽입 이미지

간단한 샘플 화면 입니다.



사용자 삽입 이미지


격리저장소의 용량을 증가 시키는 방법과 같이 사용자의 이벤트(Click) 에 의해서만 디바이스 접근이 가능합니다.

이때 사용자에게 디바이스 접근 허가를 받습니다.


사용자 삽입 이미지

멋진 인디의 모습(?)이 찍히는 군요. ^^;;;;




여기까지 Silverlight 4 웹캠 사용 방법 이었습니다.


[샘플 페이지]

[샘플소스]

[Silverlight 4  Developer Runtime]

2009/11/21 11:29 2009/11/21 11:29
inde 이 작성.

Silverlight 4 beta 가 나왔습니다. 따라가기 좀 힘들지만 그래도 나올때마다 감탄을 연발하게 되는군요.
오늘 부터 Silverilght 4의 신기술을 하나하나 맛보고 넘어 가도록 하겠습니다.

우선 Silverlight 4를 하기 앞서 개발 환경을 먼저 꾸려야져 ^^

1. Visualstudio 2010 아쉽게도 현재 상황으로는 Silverlight 4는 VisualStudio 2010 에서만 가능한것 같습니다.

Visualstudio 2010 은 현재 beta2 까지 나왔구요. 아래 주소로 다운이 가능합니다. 베타버젼이기 때문에 무료로 사용할수 있습니

다. 물론 정식이 나오면 못쓰구요 ^^

http://www.microsoft.com/visualstudio/ko-kr/try/default.mspx#download


2. Silverlight 4 Tools

다음은 방금 나온 뜨끈 뜨끈한 Silvelight4 를 설치 해야지요. 아래의 주소로 다운 가능합니다. 현재 영문버젼만 나왔습니다.

http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=9fa8afe9-cad6-4090-a7f6-7d9cdc560e2d


3. Silverlight 4 Document 파일

Silverilght 4 도움말 문서 입니다. 새로나온 4를 공부할려면 필수 이겠죠. 아래의 주소로 다운 가능합니다.

http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=b6127b9b-968c-46c2-8cb6-d228e017ad74


사용자 삽입 이미지

자 설치가 끝나고 VS2010을 실행합니다. 이제 Silverilght 4 프로젝트를 생성 해야 겠군요. 프로젝트를 생성할때 Silverlight 탭에 안보이던 놈이 눈에 띄는 군요. Silverlight 4 Tool 에서는 Business Application 이라는 놈과, RIA Service 가 기본 탑재 되었네요.



Silverlight 4는 3때와 마찬가지로 너무 많은 것이 추가 된것 같습니다. 기술습득의 시간보다 버젼업이 더 빨라 좀 부담스럽지만. MS 가 이렇게 열심히 Silverlight 만들어 주는것이 Silverlight 팬으로서는 참 기분이 좋은것 같습니다. 위 개발환경은 기존 Silverlight 개발을 하시고 계시는 분은 호환문제가 있을지 모르니깐요. 가상화방법으로 사용해보시는 것을 추천 합니다.

XP 는 VirtualPC 2007 WIN7 은 XP 모드를 사용 하시면 됩니다. 


Silverlight 하면서 살림살이좀 나아졌으면 하는 인디였습니다.

2009/11/21 11:25 2009/11/21 11:25
inde 이 작성.