u  Understand DataBinding

1.    데이터 바인딩의 개념

-      우선, UI 엘레먼트와 데이터 개체와의 연결을 만드는 과정이라고 보시면 됩니다.

-      바인딩 원본 개체의 특정 속성이 바인딩대상 엘리먼트의 의존 속성과 다르거나 원본 개체 속성의 값이 가공해야 할 경우 변환기(ValueConverter)를 통해 변경해야 합니다.

-      데이터 바인딩 기본 개념도

    데이터 바인딩의 장점  

-      모든 개체들의 속성(Property)이 바인딩을 지원합니다.

-      데이터 템플릿과 스타일을 통해 데이터표현이 자유롭고 유연합니다.

-      UI로 부터 비즈니스 로직을 완벽히 분리할 수 있습니다.

2.    데이터 흐름

-      BindingMode열거형

속성

설명

OneWay

바인딩이 만들어지거나 바인딩 원본 개체 속성이 변경되었을 때 바인딩 대상 개체의 속성 값을 변경합니다.

OneTime

바인딩이 만들어질 때만 바인딩 대상 개체의 속성 값을 변경합니다.

TwoWay

바인딩 원본과 대상 개체의 속성 중 하나가 변경되면 나머지 하나의 속성 값을 변경합니다.

-      OneWay, TwoWay와 같이 바인딩 원본 개체의 속성값이 변경되었을 때 대상 개체의 속성값을 변경하기 위해서는 INotifyPropertyChanged 인터페이스를 구현해야만 합니다.

3.    데이터 바인딩 표현식

<object Property=”{Binding}” …/>

<object Property=”{Binding propertyPath}” …/>

<object Property=”{Binding oneOrMoreBindingProperties}” …/>

<object Property=”{Binding propertyPath , oneOrMoreBindingProperties }” …/>

 

u  Sample Code

1.    마우스 왼쪽 버튼 클릭 이벤트로 TextBlock 색깔 바꾸기

-      텍스트 블록에 Foreground 데이터 바인딩하기

Code

Page.xaml

<UserControl x:Class="DemoSample2.Page"

    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" >

        <TextBlock x:Name="TextBlock1" Margin="10" Foreground="{Binding ChangingColor}">DataBinding Sample Code</TextBlock>

    </Grid>

</UserControl>

 

Page.xaml.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 DemoSample2

{

    public partial class Page : UserControl

    {

 MyColors myColor = new MyColors();

 

        public Page()

        {

            InitializeComponent();

 

            myColor.ChangingColor = new SolidColorBrush(Colors.Red);

            this.TextBlock1.DataContext = myColor;

        }

    }

 

    public class MyColors

    {

        private SolidColorBrush changingColor;

 

        public SolidColorBrush ChangingColor

        {

            get { return changingColor; }

            set { changingColor = value; }

        }

    }

}

Description

ð  Page.xaml 텍스트 블록의 Foreground 속성에 바인딩합니다.

ð  데이터 바인딩을 위한 원본 개체를 만들기 위해 MyColors 클래스를선언하였습니다.

ð  Page()에서 Object 개체에 데이터 바인딩을 지정하였습니다.

Result

 

-      마우스 왼쪽 버튼 클릭 이벤트 추가

Code

Page.xaml

<TextBlock x:Name="TextBlock1" Margin="10" Foreground="{Binding ChangingColor}" MouseLeftButtonDown="TextBlock1_MouseLeftButtonDown">DataBinding Sample Code</TextBlock>

 

Page.xaml.cs

private void TextBlock1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)

{

    myColor.ChangingColor = new SolidColorBrush(Colors.Black);

}

Description

ð  마우스 왼쪽 버튼 클릭 이벤트를 추가하였습니다. 빌드 후, 결과 화면을 보시면, 상단 이미지와 동일하게 텍스트 블록 색깔 변화가없는 것을 볼 수 있습니다.

ð  속성 값 변경을 감지해서 대상 속성의 값을 변경하기 위해서는INotifyPropertyChanged 인터페이스를 반드시 구현해 주어야 합니다.

-      INotifyPropertyChanged인터페이스 구현

Code

public class MyColors : INotifyPropertyChanged

{

    public event PropertyChangedEventHandler PropertyChanged;

 

    private SolidColorBrush changingColor;

    public SolidColorBrush ChangingColor

    {

        get { return changingColor; }

        set

        {

            changingColor = value;

            NotifyPropertyChaged("ChangingColor");

        }

    }

 

    private void NotifyPropertyChaged(string propertyName)

    {

        if (PropertyChanged != null)

        {

            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

        }

    }

}

2.    ListBox컨트롤에 DataBinding 하기

-      Part3.“Naver OpenAPI 를 이용한 Book검색코드에서 DataGrid 컨트롤를 삭제하고, ListBox 컨트롤로 변경한 후, 데이터 보여주기

Code

Page.xaml

// DataGrid 컨트롤 삭제하고, ListBox 컨트롤 로 대체함.

<ListBox x:Name="lbResult" Grid.Row="1"></ListBox>

 

Page.xaml.cs

void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)

{

    if (e.Error == null)

    {

        //Using LINQ to XML to Parse NaverOpenAPI XML Items into Book Class

        XDocument xmlBooks = XDocument.Parse(e.Result);

 

        var books = from book in xmlBooks.Descendants("item")

                    select new Book

                    {

                        BookName = (string)book.Element("title"),

                        LinkUrl = new Uri((string)book.Element("link")),

                        ImageUrl = new Uri((string)book.Element("image")),

                        Author = (string)book.Element("author"),

                        Price = (int)book.Element("price"),

                        Publisher = (string)book.Element("publisher"),

                        PubDate = (string)book.Element("pubdate"),

                        ISBN = (string)book.Element("isbn"),

                        Description = (string)book.Element("description")

                    };

 

        // XML Parse 한 데이터 바인딩하기

        lbResult.ItemsSource = books;

    }

}

Result

Description

ð  검색 버튼 클릭 시, ListBox 에 해당 데이터 영역에바인딩된 컬렉션명이 나타나는데, ListBox 컨트롤 부분에 <ListBox x:Name="lbResult" DisplayMemberPath="BookName" Grid.Row="1"></ListBox> 어떤 데이터를보여줄지 매핑을 하지 않았기 때문입니다. 위와 같이 DisplayMemberPath를 지정해 주시면,아래와 같이 원하는 데이터를 화면에 보여줍니다.


-      ListBox.ItemTemplate를 이용한 DataTemplate 구현하기

Code

Page.xaml

<ListBox x:Name="lbResult" Grid.Row="1">

    <ListBox.ItemTemplate>

        <DataTemplate>

            <StackPanel Orientation="Vertical">

                <StackPanel Orientation="Horizontal">

                    <TextBlock Margin="5">책 이름 : </TextBlock>

                    <TextBlock x:Name="txtBookName"  Margin="5" Text="{Binding BookName}"></TextBlock>

                </StackPanel>

                <StackPanel Orientation="Horizontal">

                    <TextBlock Margin="5">책 소개 :</TextBlock>

                    <TextBlock x:Name="txtBookDesc" Margin="5" Text="{Binding Description}"></TextBlock>

                </StackPanel>

                <StackPanel Orientation="Horizontal">

                    <TextBlock Margin="5">책 발행일 :</TextBlock>

                    <TextBlock x:Name="txtBookPubDate" Margin="5" Text="{Binding PubDate}"></TextBlock>

                </StackPanel>

            </StackPanel>

        </DataTemplate>

    </ListBox.ItemTemplate>

</ListBox>

Result


Description

ð  ListBox 1개 이상의 정보를 보여줄 경우, ListBox 컨트롤의 ItemTemplate안에 DateTemplate를 정의하여 표현하고자하는 UI를 표현할 수 있습니다.

ð  DataTemplate 안에는 한 개의 컨트롤만 사용 가능하나, 여러 개의 컨트롤을 사용할 경우, StackPanel를 감싸줘서 사용할 수 있습니다.

3.     Tooltips (중요)

-      Part3“Silverlight Network 이해하기 에서 Silverlight Application보안을 위한 URL 접근이 제약되어 있고, 보안 정책 파일을 통해 특정 클라이언트의 접근을허용할 수 있다고 설명 드렸습니다. 우선 샘플 코드를 통해 자세한 설명을 이어가겠습니다.

-      ListBox컨트롤의 ItemTempalte 에검색한 책 이미지를 넣어보겠습니다.

Code

Page.xaml

<ListBox x:Name="lbResult" Grid.Row="1" >

    <ListBox.ItemTemplate>

        <DataTemplate>

            <StackPanel Orientation="Vertical">

                <StackPanel Orientation="Horizontal">

                    <TextBlock Margin="5">책 이미지 :</TextBlock>

                    <Image Source="{Binding ImageUrl}" Width="16" Height="10"></Image>

                </StackPanel>

                <StackPanel Orientation="Horizontal">

                    <TextBlock Margin="5">책 이름 :</TextBlock>

                    <TextBlock x:Name="txtBookName"  Margin="5" Text="{Binding BookName}"></TextBlock>

                </StackPanel>

                <StackPanel Orientation="Horizontal">

                    <TextBlock Margin="5">책 소개 :</TextBlock>

                    <TextBlock x:Name="txtBookDesc" Margin="5" Text="{Binding Description}"></TextBlock>

                </StackPanel>

                <StackPanel Orientation="Horizontal">

                    <TextBlock Margin="5">책 발행일 :</TextBlock>

                    <TextBlock x:Name="txtBookPubDate" Margin="5" Text="{Binding PubDate}"></TextBlock>

                </StackPanel>

            </StackPanel>

        </DataTemplate>

    </ListBox.ItemTemplate>

</ListBox>

Result


Description

ð  결과 화면처럼 에러 코드 : 4001 , 범주 : ImageError , 메시지 : AG_E_NETWORK_ERROR 가 발생하는 것을 볼 수 있습니다. 좀 더 자세히 알아보기 위해 HttpWatch, Fildder IE 개발 툴을 사용하여 요청한기록(아래 이미지)을 보면 요청한 도메인 최상위 루트에 clientaccesspolicy.xml 파일과 crossdomain.xml를먼저 요청하는 것을 볼 수 있습니다. 크로스 도메인 접근시 자동으로 요청하는 2개의 파일입니다.

ð  Clientaccesspolicy.xml 파일은 Silverlight에서 사용하는 보안 정책 파일이고, Crossdomain.xml 파일은 기존에 어드비 플래시에서 사용하는 정책 파일로, 어떤 파일과 어떤 디렉토리를 접근 허용할지를 설정해 놓은 규약서라고 보시면 됩니다.

-      보안 정책 파일 작성하고 배포하기

ð  이 사이트의 모든 경로나 파일의 접근이 가능하도록 작성하였습니다.

Code

Clientaccesspolicy.xml

<?xml version="1.0" encoding="utf-8"?>

<access-policy>

  <cross-domain-access>

    <policy>

      <allow-from http-request-headers="*">

        <domain uri="*"/>

      </allow-from>

      <grant-to>

        <resource path="/" include-subpaths="true"/>

      </grant-to>

    </policy>

  </cross-domain-access>

</access-policy>

추가 설명 (예시)

<resource path="/demo" include-subpaths="false"/> 로 지정시,

허용되는 접근

demo#intro

/demo?bar=true#intro

허용되지 않는 접근

/demo

/demo.txt

/demo/sample

/demo/sample.txt

/demo/sample?bar=true

/sample

 

<resource path="/demo" include-subpaths="true"/> 로 지정시,

허용되는 접근

/demo/sample

/demo/sample.txt

/demo/sample?bar=true

/demo#intro

허용되지 않는 접근

/sample

Crossdomain.xml

<?xml version="1.0"?>

 

<!DOCTYPE cross-domain-policy SYSTEM

"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">

 

<cross-domain-policy>

  <allow-access-from domain="*"/>

  <allow-http-request-headers-from domain="* " headers="*" />

</cross-domain-policy>

ð  위 코드와 같이 작성한 후, 사이트 최상위 루트에 배포하시면 됩니다.

 

+ Recent posts