시작하세요.  Silverlight

#7-1 Layout

 이번 강좌에서는 Silverlight 에서 가장 기본이 되는 Layout 에 대해 알아 보도록 하겠습니다. Layout 은 위치를 를 잡아 주는 아주 중요한 컨트롤 입니다. 레이아웃 컨트롤의 종류는 기본적으로  Canvas , Grid ,StackPanel 등이 있고 Silverlight Toolkit 에 포함된 확장 컨트롤인 WrapPanel, DockPanel 등이 대표적인 레이아웃 컨트롤 이라 할 수 있습니다.

# Canvas Control
 레이아웃 컨트롤은 자식 컨트롤의 위치를 잡는 방법에서 큰 차이 점이 있습니다. 그중 Canvas 컨트롤에 대해 알아 보도록 하겠습니다.
 
 Silverlight 가 막 세상에 나왔을때는 지금과 같은 많은 컨트롤들이 지원 되지는 않았습니다. 그때는 레이아웃 컨트롤 역시 마찬가지로 Canvas 밖에 지원하지 않았습니다. 이처럼 가장 기본이 되었던 Canvas 컨트롤의 특징은 자식 UIElement 들의 위치를 잡을때 상단과 좌측을 기준으로 위치를 잡는것이 큰 특징 입니다.


사용자 삽입 이미지

Canvas 는 <Canvas/> 태그를 사용하고 자식 UIElement 의 위치는 Canvas.Top , Canvas.Left 속성을 이용합니다.
    <Canvas Background="LightGray">
        <Button Width="100" Height="30" Canvas.Left="100" Canvas.Top="50" Content="Click!!"/>
    </Canvas>

사용자 삽입 이미지

모든 XAML 들은 동적으로 생성이 가능한데 , Canvas 역시 동적으로 생성이 가능합니다. Canvas 컨트롤을 동적으로 생성에 기본 레이아웃 컨트롤인 LayoutRoot 컨트롤의 자식으로 추가해 보겠습니다.( 간혹 LayoutRoot 를 지워 버리시는 분이 있으신데.... 좋지 않은 행동입니다.)

Canvas can = new Canvas();
LayoutRoot.Children.Add(can);

레이아웃 컨트롤은 다수의 자식 UIElement 들을 포함시킬 수 있는 컨트롤 입니다. Canvas 컨트롤 역시 다수의 자식 컨트롤을 추가 할수 있는데 동적으로 자식의 컨트롤을 추가하는 방법은  다음과 같습니다.

Button btn = new Button();
btn.Width = 100;
btn.Height = 30;
btn.Content = "Click!!";

can.Children.Add(btn);

이렇게 레이아웃 컨트롤에 있는 Children 에 자식 UIElement  를 추가하면 됩니다. Canvas 에 자식이 추가되게 되면 기본적으로 자식은 (0,0) 좌표에 위치 하게 됩니다.

사용자 삽입 이미지
이때 자식 UIElement 의 위치를 잡기위해선 다음과 같은 동적 코딩으로 변경 할 수 있습니다.

Canvas.SetLeft(btn, 100);
Canvas.SetTop(btn, 50);


사용자 삽입 이미지

Canvas 에 추가된 자식 UIElement 들은 레어어와 같이 계층적으로 들어 가게 됩니다.  이 계층은 마지막에 추가된것이 가장 위로 가는 특징이 있는데 XAML 에서 다음과 같이 자식의 UIElement 추가 되었을 때는 마지막에 들어간 자식이 가장 화면 위에 나타 납니다. 이것은 Canvas 뿐만 아니라 자식을 갖는 모든 컨트롤이 공통 됩니다.

사용자 삽입 이미지
하지만 이 계층은 임위로 그 위치를 지정 할 수가 있는데요. Zindex 가 그 역할을 합니다. Zindex 의 값은 정수형 값이 들어 가면 이수의 크기가 클수록 가장위로 올라 갑니다.

<Canvas>
            <Rectangle Width="100" Height="100"
                       Fill="Red" Canvas.Left="150"
                       Canvas.Top="100" Canvas.ZIndex="1"></Rectangle>
            <Rectangle Width="100" Height="100"
                       Fill="Blue" Canvas.Left="190"
                       Canvas.Top="140" Canvas.ZIndex="2"></Rectangle>
            <Rectangle Width="100" Height="100"
                       Fill="Yellow" Canvas.Left="220"
                       Canvas.Top="170" Canvas.ZIndex="1"></Rectangle>
</Canvas>


사용자 삽입 이미지

동적으로도 Canvas.SetZIndex(UIElement element , int value) 를 이용하면 변경 할수 있습니다.



2010/01/05 17:53 2010/01/05 17:53
inde 이 작성.

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 이 작성.