블로그 이미지
Sunny's

calendar

1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Notice

2009. 4. 16. 11:28 WPF, Silverlight

[XAML]

<Grid Width="320" Height="480">
    <Grid.Background>
        <ImageBrush ImageSource="Background.jpg"/>
    </Grid.Background>
    <Canvas ClipToBounds="True" Margin="0,82,0,40">
        <StackPanel Background="WhiteSmoke" Canvas.Top="0" x:Name="Panel">
            <StackPanel.Resources>
                <Style TargetType="Button">
                    <Setter Property="Height" Value="30"/>
                    <Setter Property="Width" Value="300"/>
                    <Setter Property="Margin" Value="10"/>
                </Style>
            </StackPanel.Resources>
        </StackPanel>   
    </Canvas>
</Grid>

[C#]

void Window1_Loaded(object sender, RoutedEventArgs e)
{
    for (int i = 0; i < 30; i++)
    {
        Button Item = new Button();
        Item.Content = "ITEM #" + i.ToString();
        Panel.Children.Add(Item);
    }

    ScrollPanel ScrollPanel = new ScrollPanel(Panel);

}

[C# - ScrollPanel.cs]

public class ScrollPanel
{

    private const int MinimunRange = 30;
    private const int MinimumTime = 100;

    private FrameworkElement Target { get; set; }
    private FrameworkElement TargetParent { get; set; }

    private Point BeginPoint;
    private Point LastPoint;
    private DoubleAnimation MoveAnimation;
    private double LastMoveTime;

    public ScrollPanel(FrameworkElement TargetElement)
    {
        MoveAnimation = new DoubleAnimation();
        MoveAnimation.Duration = TimeSpan.FromMilliseconds(1000);
        MoveAnimation.DecelerationRatio = 0.8;

        Target = TargetElement;
        TargetParent = Target.Parent as FrameworkElement;
        Target.PreviewMouseMove += new MouseEventHandler(Target_MouseMove);
        Target.PreviewMouseDown += new MouseButtonEventHandler(Target_MouseDown);
        Target.PreviewMouseUp += new MouseButtonEventHandler(Target_MouseUp);

    }
    void Target_MouseUp(object sender, MouseButtonEventArgs e)
    {
        Target.ReleaseMouseCapture();
    }

    void Target_MouseDown(object sender, MouseButtonEventArgs e)
    {
        BeginPoint = e.GetPosition(Target);
        Target.CaptureMouse();
    }
    void Target_MouseMove(object sender, MouseEventArgs e)
    {

        if (e.LeftButton != MouseButtonState.Pressed) return;

        // 너무 빨리 움직였을경우
        if ((DateTime.Now.TimeOfDay.TotalMilliseconds - LastMoveTime) < MinimumTime) return;
        LastMoveTime = DateTime.Now.TimeOfDay.TotalMilliseconds;

        // 마우스가 제자리 일 경우
        Point CurrentPointParent = e.GetPosition(TargetParent);
        if (CurrentPointParent.Y == LastPoint.Y) return;
        LastPoint = CurrentPointParent;

        // 마우스가 너무 적게 움직였을 경우
        Point CurrentPoint = e.GetPosition(Target);
        double MovePosition = (CurrentPoint.Y - BeginPoint.Y);
        if (Math.Abs(MovePosition) < MinimunRange) return;

        MoveAnimation.By = MovePosition*1.5;
        Target.BeginAnimation(Canvas.TopProperty, MoveAnimation);

    }

}

XAML코드와 Window Loaded Event부분은 UI구성에 필요한 부분이므로 설명은 생략하도록 하겠습니다. ScrollPanel Class를 살펴보겠습니다. ScrollPanel은 생성자로 스크롤이 될 Target Control을 입력받으며 내부적으로 Target과 Target의 부모를 가지고 있습니다. 그리고 MouseEvent 가 발생할 경우 에 따라서 움직이는 Animation을 적용시켰습니다. 코드를 보고 이해가 안되는 부분이나 추가 설명이 필요하신 부분은 리플 달아주세요.

아래는 전체 소스코드 파일입니다.

posted by Sunny's