GSI

데이터 바인딩#1 - 기본
데이터 바인딩#2 - Binding Mode
데이터바인딩#3 - DataContext
데이터 바인딩#4 - TextBox vs Run
데이터 바인딩#5 - FrameWorkElement Demo
데이터 바인딩#6 - IValueConverter

저번 시간까지 텍스트에 대해서 알아 봤습니다.
이번 시간은 FrameElement를 사용하게 되면 좋은 효과를 볼 수 있는 데모를 보면서 의존 프로퍼티의 장점을 보도록 하겠습니다.

의존 프로퍼티 시스템은 내부에 통보 장치가 구현되어 있어서 바인딩 소스가 의존 프로퍼티가 될 필요가 없지만 의존 프로퍼티일 경우 상당히 유용해질 수 있습니다.
이 말은 소스가 의존 프로퍼티가 없어도 타겟의 경우 소스의 값을 참조 할 수 있지만, 의존 프로퍼티가 있을 경우 통지 메시지를 받을수 있어서 소스이지만 타깃의 기능을 사용할 수 있다 정도로 이해 하시고 다음 소스를 보시면 더 이해가 빠를 겁니다.

우선  FrameWorkElement 를 상속받은 클래스를 하나 생성합니다.

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Media;

namespace WpfApplication1
{
    class SimpleElement : FrameworkElement
    {
        // DependencyProperty 정의
        public static DependencyProperty NumberProperty;

        // 정적 생성자에 DependencyProperty 생성
        static SimpleElement()
        {
            NumberProperty =
                DependencyProperty.Register("Number", typeof(double),
                    typeof(SimpleElement),
                    new FrameworkPropertyMetadata(0.0,
                        FrameworkPropertyMetadataOptions.AffectsRender));
        }

        // DependencyProperty를 CLR 프로퍼티를 노출
        public double Number
        {
            set { SetValue(NumberProperty, value); }
            get { return (double)GetValue(NumberProperty); }
        }

        // MeasureOverride를 오버라이딩해 크기를 하드 코딩
        protected override Size MeasureOverride(Size availableSize)
        {
            //return base.MeasureOverride(availableSize);
            return new Size(200, 50);
        }

        // Number 프로퍼티를 보여주는 OnRender
        protected override void OnRender(DrawingContext dc)
        {
            dc.DrawText(
                new FormattedText(Number.ToString(),
                    CultureInfo.CurrentCulture, FlowDirection.LeftToRight,
                    new Typeface("Times New Roman"), 12,
                    SystemColors.WindowTextBrush),
                    new Point(0, 0));
        }
    }
}


이 클래스는 double라는 double 타입의 프로퍼티를 하나 정의 했습니다. 이 프로퍼티는 NumberProperty라는 DependencyProperty의 지원을 받게 됩니다.
FrameworkPropertyMetadata 는 초기값이 0 이며, 프로퍼티에 변화가 생기면 OnRender가 호출되고 화면이 갱신 됩니다.

이제 이 코드를 적용할 xaml 코드를 보겠습니다.
<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:src="clr-namespace:WpfApplication1"
    Title="Window1" Height="300" Width="300">
   
    <StackPanel>
        <ScrollBar  Orientation="Horizontal"
                    Margin="24"
                    Maximum="100"
                    LargeChange="10"
                    SmallChange="1"
                    Value="{Binding ElementName=Simple, Path=Number, Mode=OneWayToSource}" />
       
        <src:SimpleElement x:Name="Simple" HorizontalAlignment="Center" />
       
        <ScrollBar  Name="scroll"
                    Orientation="Horizontal"
                    Margin="24"
                    Maximum="100"
                    LargeChange="10"
                    SmallChange="1"
                    Value="{Binding ElementName=Simple, Path=Number, Mode=TwoWay}" />
       
        <src:SimpleElement HorizontalAlignment="Center" Number="{Binding ElementName=scroll, Path=Value, Mode=OneWay}"/>
    </StackPanel>
</Window>

SimpleElement 엘리먼트상의 x:Name 속성은 FrameworkElement를 상속받지 않은 XAML 엘리먼트를 위한 속성이다. 이 엘리먼트들은 Name 프로퍼티가 없기 때문에 Name 프로퍼티를 사용할 경우에는 에러가 발생한다. 이 에러는 "SimpleElement가 동일한 어셈블리에서 구현되었기 때문에 Name 속성 대신에 x:Name 속성을 사용해야함" 이다.

이 내용을 사용해서 행동을 해보면 아래와 같은 행동이 일어 난다.
첫 번째 ScrollBar를 움직이면  나머지 모든 정보가 바뀌게 된다.
두 번째 ScrollBar를 움직이면 첫 번째 ScrollBar는 움직이지 않는다.

사용자 삽입 이미지


첫 번째 ScrollBar는 OneWayToSource로 되어 있기 때문에 ScrollBar가 타깃이 되지만 내부적으로는 소스형태가 되는 것이다. 이전 강좌에서 말한 것처름 타깃이 소스로 날아 가는거라고 했다. 즉, ScrollBar의 값이 SimpleElement로 전달 되게 되는 것이다. 이것은 SimpleElement가 의존 프로퍼티의 형태를 뛰지 않았을때를 가정한다.

두 번째 ScrollBar는 TwoWay 형태를 취하고 있기 때문에 Element 로 값을 업데이트 하게 된다. x:Name 를 가지고 있는 SimpleEment로도 값을 보내게 되는 것이다.

설명은 여기 까지며 덫붙여 설명하면,

SimpleElement() 에 포함되어 있는 FrameworkPropertyMetadataOptions 의 옵션에는 데이터 바인딩을 처리해 줄 수 있는 옵션들이 포함되어 있다.

두 번째 ScrollBar의 Mode=OneWay를 하게 되면 첫 번째 ScrollBar와 연동되지 않으며,
첫번째 SimpleElement와도 연동되지 않는다.
OneWay로 하게 되면 위쪽의 SimpleEment의 값을 타깃으로 받을 수만 있고 넘겨 줄 수가 없게 되는 것이다.

이번 강좌는 여기까지 ^^.
OneWay, TwoWay, OneWayToSource에 대해서 조금은 더 테스트를 해보면서
확실하게 알아갈 필요가 있는듯 합니다.
FrameWorkElement의 이용에 대해서도 한번더 이해를 할 수 있는 시간이였습니다.

모두 수고 ^^

참고 ^^
본 내용은 "찰스페졸드의 WPF"의 내용을 이해 하고 나름 생각과 같이 정리한 겁니다.
제제가 가해질 경우 바로 삭제하도록 하겠습니다. ^^;
Posted by gsi
: