본문 바로가기

silverlight

Behavior 만들기

Silverlight 3 에서는 Behavior 를 지원합니다.
Behavior란 사전적인 해석에서 알 수 있듯이, 동작을 뜻합니다. 이 동작이란 것은, Dependency Object의 동작이 될 수도 있고, FrameworkElement의 Event에 대한 Trigger가 될 수 있습니다.

Behavior를 Silverlight 3 에서 구현하는 방법 입니다.
1. Dependency object 의 Behavior 정의
우선, Dependency object의 Behavior를 정의 하기 위해서는,
Program Files > Microsoft Expression > Bledn 3 Preview > Libraries > Silverlight > Microsoft.Expression.Interativity.dll 을 참조 추가 해야 합니다.

참조 추가를 한 뒤, Microsoft.Expression.Interactivity.dll 에 있는 Behavior<T> : where T : DependencyObject 를 상속 받아서 Behavior 클래스를 만듭니다.
public class DragBehavior : Microsoft.Expression.Interactivity.Behavior<UIElement>
{
}

그리고, DependencyObject에 Behavior를 Add 된 경우 실행 되는 Behavior.OnAttached 메소드를 구현(override)하여, Behavior를 정의합니다.
public class DragBehavior : Behavior<UIElement>
{
    private bool isDragging = false;
    private UIElement attachedElement;
    private UserControl parent;

    Point lastPosition;
    TranslateTransform translatePosition;

    protected override void OnAttached()
    {
        attachedElement = this.AssociatedObject;
        parent = Application.Current.RootVisual as UserControl;
        attachedElement.MouseLeftButtonDown += new MouseButtonEventHandler(MouseIsDown);
        attachedElement.MouseLeftButtonUp += new MouseButtonEventHandler(MouseIsUp);
        attachedElement.MouseMove += new MouseEventHandler(MouseIsMoving);
    }

    void MouseIsMoving(object sender, MouseEventArgs e)
    {
        if (isDragging)
        {
            Point currentPosition = e.GetPosition(parent);

            double dX = currentPosition.X - lastPosition.X;
            double dY = currentPosition.Y - lastPosition.Y;

            this.lastPosition = currentPosition;

            Transform oldTransform = attachedElement.RenderTransform;
            TransformGroup rt = new TransformGroup();
            TranslateTransform newPos = new TranslateTransform();
            newPos.X = dX;
            newPos.Y = dY;

            translatePosition = newPos;

            if (oldTransform != null)
            {
                rt.Children.Add(oldTransform);
            }
            rt.Children.Add(newPos);

            MatrixTransform mt = new MatrixTransform();
            mt.Matrix = rt.Value;

            attachedElement.RenderTransform = mt;
        }
    }

    void MouseIsUp(object sender, MouseButtonEventArgs e)
    {
        isDragging = false;

        attachedElement.ReleaseMouseCapture();
    }

    void MouseIsDown(object sender, MouseButtonEventArgs e)
    {
        isDragging = true;
        lastPosition = e.GetPosition(parent);
        attachedElement.CaptureMouse();
    }
}

참고로 위 코드는 Sample Silverlight 3 Behaviors 에서 다운 받은 자료 중 하나로 UIElement를 Drag 가능하도록 하는 Behavior입니다.
Behavior class 를 정의 한 뒤 Expression Blend 3 Preview에서 솔루션을 Open하면, Asset Library의 Behaviors에 추가 되신 것을 확인 할 수 있습니다.

작성하신 DragBehavior를 Drag가 가능하게 하기 위한 DependencyObject에 Drag하여 추가하시면 비하인드 코드 상에서 아무런 조작을 하지 않아도, DragBehavior가 Add 된 DependencyObject는 실행시 Drag가 가능하게 됩니다.


2. FrameworkElement의 Event에 대한 Trigger 구현
Microsoft.Expression.Interativity.TargetedTriggerAction<FrameworkElement> 를 상속받아 대상이 되는 FrameworkElement의 Event에 대한 Trigger를 구현하는 Behavior class를 정의 할 수 있습니다.
public class PopupBehavior : Microsoft.Expression.Interactivity.TargetedTriggerAction<FrameworkElement>
{
    protected override void Invoke(object parameter)
    {
        MessageBox.Show("Popup!");
    }
}

위 코드는 FrameworkElement의 Event에 대하여 MessageBox를 띄워주게 될 것입니다.
이렇게 구현 된 클래스를 빌드 한 뒤, Microsoft Expression Blend 3 Preview에서 솔루션을 Open하면 Asset Library의 Behaviors 에 추가 되 있습니다. PopupBehavior를 Button에 연결 해 보겠습니다.


TargetedTriggerAction Behavior는 Target이 되는 FrameworkElemet에 연결 시, Properties에 Trigger 속성을 설정하는 부분이 나옵니다. 여기서 EventName을 정하면, 해당하는 Event의 Trigger로 TargetedTriggerAction Behavior가 동작하게 됩니다. 정확히는 override 된 TargetedTriggerAction.Invoke(object parameter) 함수가 실행 되는 것입니다.

또, Property를 추가하여 사용자 원하는 Message를 입력받아 출력할 수 있도록 할 수 있습니다.

public class PopupBehavior : Microsoft.Expression.Interactivity.TargetedTriggerAction<FrameworkElement>
{
    [Category("Message Box Properties")]
    public string PopupText
    {
        get { return (string)GetValue(PopupTextProperty); }
        set { SetValue(PopupTextProperty, value); }
    }

    public static readonly DependencyProperty PopupTextProperty =     DependencyProperty.Register("Popup Text"typeof(string), typeof(PopupBehavior), new PropertyMetadata("Input Popup Text!"));

    protected override void Invoke(object parameter)
    {
        MessageBox.Show(PopupText);
    }
}

[Category("카테고리명")] 으로 Property에 대한 Category를 지정하게 되면, Microsoft Expression Blend 3 Preivew 상에서 다음 그림에서 처럼 표시 됩니다.


이렇게 되면, 사용자가 직접 입력한 PopupText가 Button의 Cilck Event 시 실행되게 됩니다.