Silverlight 예제 100선

# Binding + Open API + LINQ  를 이용한 이미지 검색


# 프로젝트 만들기

검색 Application 을 만들기 위해 새 프로젝트를 생성 합니다. 상단 메뉴에서 파일-> 새로만들기 -> 프로젝트 ->   Visual C# -> Silverlgiht 텝에서 Silverlight 응용프로그램 으로 프로젝트를 생성 합니다. 프로젝트 이름은 ImageSearch 라고 하겠습니다. ^^

사용자 삽입 이미지



# MainPage.xaml 수정 하기

이번에 만들 검색 App 의 화면은 간단합니다. 키워드가 들어간  TextBox 박스 한개와 , 리스트가 뿌려질 ListBox 1개 그리고 검색을 실행할 버튼 한개를 구성하여 App UI 만들도록 하겠습니다.

MainPage.xaml  페이지를 열어 아래와 같이 수정 합니다.
<UserControl x:Class="SearchApp.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" Width="600" Height="400">
  <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="50"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <TextBox Width="450" HorizontalAlignment="Left" Grid.Row="0" Height="30" Margin="20,0,0,0" x:Name="KeyWord"/>
        <Button Width="100" Height="30" HorizontalAlignment="Right" Margin="0,0,20,0" Content="Search" x:Name="SearchButton"/>
        <ListBox Grid.Row="1" Margin="20" x:Name="ImageListBox">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Image Width="50" Height="50" HorizontalAlignment="Left" Source="{Binding ImageUrl}" Stretch="UniformToFill"/>
                        <HyperlinkButton Margin="60,0,20,0" Content="{Binding Title}" NavigateUri="{Binding LinkUrl}" VerticalAlignment="Center" TargetName="_Blank"/>
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</UserControl>

사용자 삽입 이미지

# LINQ 참조 추가하기

LINQ 는 기본적으로 시스템에 참조 되어 있지만 XML LINQ는 시스템 참조에 추가되어 있지 않습니다. 그래서 Xml Linq 를 직접 추가 해야 됩니다.

사용자 삽입 이미지
솔루션 탐색기 에서 참조부분에 우클릭을 하신 후 참조 추가를 누릅니다.

사용자 삽입 이미지
System.Xml.Linq 를 선택하고 확인을 누릅니다.

사용자 삽입 이미지
참조 트리에 추가된 모습을 확인 할 수 있습니다.


# MainPage.xaml.cs 수정하기
 

자!! 이제 본격적으로 Silverlight Application 을 코딩하기 시작 하겠습니다. 우선은 검색 App 에서 필요한 네임스페이스를 참조 합니다.


using System.Collections.ObjectModel;
using System.Xml.Linq;
using System.Windows.Browser;


이제 바인딩에 필요한 데이타를 만들기 위해 데이타 모델을 선언 합나다. 바인딩이 될 멤버는 꼭 Property 로 선언 되어야 합니다.

    public class ImageData
    {
        public string ImageUrl { get; set; }
        public string LinkUrl { get; set; }
        public string Title { get; set; }
    }

03 ImageUrl : 검색결과의 이미지 경로
04 LinkUrl : 원본 이미지의 경로
05 Title : 제목  



    public partial class MainPage : UserControl
    {
        string apiKey = "API 키";
        ObservableCollection imageList = new ObservableCollection();
        public MainPage()
        {
            InitializeComponent();
            Loaded += (object sender, RoutedEventArgs e) =>
                {
                    ImageListBox.ItemsSource = imageList;
                };
            SearchButton.Click += (object sender, RoutedEventArgs e) =>
                {
                    Search();
                };
            KeyWord.KeyUp += (object sender, KeyEventArgs e) =>
                {
                    if (e.Key == Key.Enter)
                    {
                        Search();
                    }
                };
        }
        void Search()
        {
            if (KeyWord.Text.Length <= 0)
            {
                MessageBox.Show("검색어를 입력하세요.");
                KeyWord.Focus();
                return;
            }
            
            WebClient wc = new WebClient();
            
            wc.DownloadStringAsync(new Uri(string.Format("http://openapi.naver.com/search?key={0}&query={1}&target=image&start=1&display=100",apiKey,HttpUtility.UrlEncode(KeyWord.Text))));
            wc.DownloadStringCompleted += (object sender, DownloadStringCompletedEventArgs e) =>
            {
                XDocument doc = XDocument.Parse(e.Result);
                var xmlData = from data in doc.Descendants("item")
                              select new ImageData
                              {
                                  ImageUrl = (string)data.Element("thumbnail"),
                                  LinkUrl = (string)data.Element("link"),
                                  Title = (string)data.Element("title")
                              };

                imageList.Clear();
                foreach (ImageData data in xmlData)
                {
                    imageList.Add(data);
                }
            };
        }       
    }

03 OPEN API 필요한 키를 선언 합니다. dev.naver.com 에 가시면 쉽게 키를 얻을 수 있습니다.
04 바인딩 에 찰떡 궁합인 ObservableCollection 객체인 imageList 를 선언 하였습니다.
08 Silverlight Application 이 로드 되었을때 바인딩 을 연결 합니다.
12 검색 버튼을 클릭했을때 검색을 시작합니다.
16 키워드 입력 박스에서 엔터 키 이벤트가 발생 되었을때 검색을 시작 합니다.
26 키워드 입력 박스에 아무것도 입력 되어 있지 않다면 경고를 발생 합니다.
33 OPEN API 데이타를 가져 오기 위해서 Webclient 를 선언 합니다.
35 DownloadStringAsync 를 이용해서 OPEN API 데이타를 요청 합니다.
36 요청한 데이타의 결과값을 가져 옵니다.
38 결과값을 XML 형식의 XDocument 객체로 파싱합니다.
39 LINQ 를 이용해서 데이타를 매칭 시킵니다.
47 기존의 검색 결과를 비웁니다.
48 검색 결과를 바인딩한 imageList 에 넣습니다.




# Silverlight Application 실행

디버그 -> 디버깅 시작을 눌러 Silverlight 프로젝트를 빌드하고 Silverlight Application 을 실행 합니다.


사용자 삽입 이미지
미적 감각이라곤 전혀 찾아 볼 수 있는 화면이 나옵니다. 키워드박스에 검색어를 놓고 버튼을 누릅니다.


사용자 삽입 이미지

어때요 Binding + OPEN API + LINQ  를 이용한 Silverlight 활용법 찹 쉽죠잉~~~
2010/01/05 14:53 2010/01/05 14:53
inde 이 작성.

요글래 뭔가를 하나 해봐야 겠다는 생각으로 이리저리 구상중에 있습니다. 주로 블로그에 설치 할수 있는 작은 위젯 위주로 만들어 볼 생각 입니다.  우선 작은 미니 그림판 위젯을 만들고 있습니다. 지금 프로토 타입 테스트 중입니다. ^^

사용자 삽입 이미지




같이 만들어 보실분~ !@!
2009/09/16 14:57 2009/09/16 14:57
inde 이 작성.

프로젝트가 끝나 간만에 한번 만들어 봤네요 ^^ Silverlight Ink Presenter 를 이용해서 만들었네요. 좀더 해서~ 서비스로 할예정 ^^

사용자 삽입 이미지


이곳으로 가시면 볼수 있습니다. -> http://www.indreams.co.kr/photo/canvas/

2009/09/11 17:44 2009/09/11 17:44
inde 이 작성.

실버라이트로 소켓통신을 하려면 원격지의 서버에서 항시 943 포트로

관련된 정책 파일을 전송해 주어야 합니다. 

실버라이트 정책 서버 데몬 입니다. 리눅스로 실버라이트 소켓을 사용하실 분은

꼭 정책 데몬을 만드셔야 합니다.

python 으로 만들어진 데몬 입니다.

[Source Download]

policydaemon.py 를 열어 log가 쌓일 주소와 , clientaccesspolicy.xml 을 수정 해주시면 됩니다.

#python policydaemon.py
[Souce policydaemon.py]

#!/usr/bin/python
#-*- coding: utf-8 -*-
import os,sys,time
from socket import *
from signal import *
from thread import *


# 로그파일
LOGFILE="./log/log"
# 정책파일
POLICYFILE="clientaccesspolicy.xml"


# 쓰레드 설정
thread_lock=allocate_lock()
thread_count=0
thread_max=10

# 키에 의한 킬
def SignalSIGINT(signum,f):
	print "Good Bye"
	WriteLog("Keyboard Kill Process")
	sys.exit()
#프로세스가 죽을때 시그널
def SignalSIGTERM(signum,f):
	print "Good Bye"
	WriteLog("Kill Process")
	sys.exit()
def DoWork(sock):
	global policy,thread_count
	thread_lock.acquire()
	thread_count=thread_count+1
	thread_lock.release()
	while(1):
		result=sock.recv(32)
		if( ""== result):
			sock.send(policy)
			WriteLog("Send Policy Message")
		sock.close()
		break
	thread_lock.acquire()
	thread_count=thread_count-1
	thread_lock.release()
#로그쓰기
def WriteLog(message):
	log="%s [%s]\n" %( time.strftime("%Y-%m-%d %H:%M:%S"),message )
	logfp=open(LOGFILE,"a")
	logfp.write(log)


#시그널 등록
signal(SIGINT,SignalSIGINT)

signal(SIGTERM,SignalSIGTERM)

# 정책파일
policy=open(POLICYFILE,"r").read()

#데몬 시작
if os.fork():
	os._exit(0)
os.setpgrp()
os.umask(0)
sys.stdin.close()



#소켓 설정
server=socket(AF_INET,SOCK_STREAM)
server.bind(("",943))
server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
server.listen(10)

print "Start Policy Server"
WriteLog("Start Policy Server")
while(1):

	client,addr=server.accept()


	WriteLog("Connect %s" % (addr[0]))
	if( thread_count <=thread_max):
		start_new_thread(DoWork,(client,))
	else:	
		WriteLog("Busy Server")
		client.close()

2009/08/18 09:11 2009/08/18 09:11
inde 이 작성.

MS 벗어나기

1. Mono-project 소개 , Moonlight 소개

2. Mac, Linux(Moonlight)  런타임 설치

3. Mac 에서의 개발환경 구성하기
4. 리눅스 에서의 개발환경 구성하기


PHP를 이용한 실버라이트 게시판  만들기

1. 웹서버 구축하기
2. 까다로운 보안 정책 이겨내기
3. 데이타 베이스 구성하기
4. PHP 를 이용해 XML 데이타 만들기
5. LINQ 사용하기
6. PHP 를 이용한 실버라이트 게시판 만들기


채팅 서비스 만들기
1. Silverlight 소켓통신 바로 알기
2. Silverlight 채팅 서비스

# 채팅서버 소스( C++, Mono C# , Python)


딥줌 서비스 만들기
1. 딥줌의 원리

2. 딥줌 컴포져 사용하기
3. 딥줌 컴포져 만들기( PHP, Python)
4. 딥줌 컴포져 서버 만들기
5. 딥줌 갤러리 서비스


웹으로 스며들기

1. HTML DOM 과의 연계

2. JavaScript 와의 연계

3. Ajax ,Jquery 와의 연계

2009/06/08 10:09 2009/06/08 10:09
inde 이 작성.

1. Silverlight 개발 환경 구성하기
 - VisualStudio 설치법
 - Expression Blend 설치

2. Visual Studio 다루기
 -프로젝트 생성하기
 -에디팅
 -빌드하기
 -환경설정

3. C# 의 기초
 -C# 기초
 -Event 와 Delegate 이해하기
 -MSDN 찾아보기

4. Silverlight 의 원리, 적용사례
 -Silverlight 런타임 알기
 -적용사례

5. XAML 다루기
 -XAML 기초
 -레이아웃 구성하기
 
6. Silverlight API
 -XAML 과 C# 코드의 이해
 -Namespace 의 구성

7. 애니메이션 다루기
 -스토리 보드의 이해
 -타이머 사용하기

8. Silverlight Control 다루기
 -컨트롤에 대한 소개
 -컨트롤 이용하기
 -유저컨트롤 만들기
 -나만의 버튼 컨트롤 만들기
 
9. XML 데이타와, 바인딩 다루기
 -LINQ 의 이해
 -원격으로 XML 데이타 가져 오기
 -바인딩에 이해
 -데이타 그리드를 이용한 게시판 만들어 보기

10. 네트워크  다루기
 -Silverlight 보안정책 살펴 보기
 -Webclient 를 이용한 원격 자원 가져 오기
 -Socket 다루기
 -소켓을 이용한 채팅 프로그램 만들어 보기

11. 미디어 다루기
 -이미지 다루기
 -나만의 갤러리 만들기
 -MediaElement 의 이해
 -나만의 UCC 플레이어 만들어보기
 -streaming.live.com 이용하기
 -딥줌에 이해
 -딥품 단체 사진 만들기

12. 템플릿 및 스타일 다루기

14. 웹과 상호작용하기
 -HTML DOM 이용하기
 -자바스크립트와 연동하기

13. 배포하기  , 서버환경 구성하기
 - XAP 의 구성
 -MINE TYPE 설정하기
 -정책파일 만들기

14. 고급
 -동적 자원 구성하기
 -격리 저장소 이용하기
 - VisualStateManager
 -Thread, Background Worker
 -MVVM 패턴
 -멀티업로드 만들어보기
 -Silverlight Toolkit 이용하기

15. Silverlight 3
 -3D 활용
 -웹하드 만들어보기
 -이미지 프로세싱
 -아웃브라우져 이용하기

2009/05/26 14:33 2009/05/26 14:33
inde 이 작성.

기존 실버라이트2 에서는 OpenFileDialog 를 제공하고 있서 쉽게 업로드와 같은 기능을 구현할수  있었습니다. 하지만 그와는 반대로 다운로드 할수 있는 기능이 없어 js 등을 이용하여 편법으로 파일 등을 다운로드 하였습니다. 하지만 실버라이트 3에서 부터는 SavaFileDialog 를 제공하기 때문에 이제는 쉽게 파일을 다운로드 할수 있습니다.




[xaml]

<UserControl x:Class="SilverlightApplication1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Visibility="Collapsed" x:Name="ProgBox" Orientation="Horizontal">
            <ProgressBar Width="200" Height="20" x:Name="Prog" Minimum="0" Maximum="100"/>
            <TextBlock x:Name="ProgCaption" Margin="10,0"/>
        </StackPanel>
        <Button x:Name="SaveButton" Content="SAVE" Width="100" Height="30" />
    </Grid>
</UserControl>


[CS]

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.IO;

namespace SilverlightApplication1
{
    public partial class MainPage : UserControl
    {
        WebClient wc = new WebClient();
        SaveFileDialog sfd = new SaveFileDialog();
        public MainPage()
        {
            sfd.Filter = "JPEG File | *.jpg";
            

            InitializeComponent();
            this.SaveButton.Click += new RoutedEventHandler(SaveButtonClick);
            wc.OpenReadCompleted += new OpenReadCompletedEventHandler(OpenReadCompleted);
            wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgressChanged);

        }
        
        /// 다운로드 상태바
        void DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            Prog.Value = e.ProgressPercentage;
            ProgCaption.Text=string.Format( "{0} %",e.ProgressPercentage);

        }
        /// 다운로드가 완료 되었을시 ( 파일저장)
        void OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            if (!e.Cancelled)
            {
                    
                using (Stream fs = sfd.OpenFile())
                {
                    
                    int length = Convert.ToInt32(e.Result.Length);
                    byte[] byteResult = new byte[length];
                    e.Result.Read(byteResult, 0, length);
                    fs.Write(byteResult, 0, byteResult.Length);
                    fs.Close();
                }
                MessageBox.Show("저장이 완료되었습니다.");
                ProgBox.Visibility = Visibility.Collapsed;
                SaveButton.Visibility = Visibility.Visible;
            }
        }
        
        /// 버튼 클릭시 다운로드를 요청 합니다. 
        void SaveButtonClick(object sender, RoutedEventArgs e)
        {
            if (true == sfd.ShowDialog())
            {
                Uri url=new Uri("http://www.indreams.co.kr/silverlight.jpg");
                
                wc.OpenReadAsync(url);
                ProgBox.Visibility = Visibility.Visible; ;
                SaveButton.Visibility = Visibility.Collapsed;
                
            }
        }

        
    }
}
2009/05/21 10:53 2009/05/21 10:53
inde 이 작성.