■ ScrollViewer 클래스에서 애니메이션 스크롤 뷰어를 사용하는 방법을 보여준다.
▶ AnimationScrollViewer.cs
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
using System.Windows; using System.Windows.Controls; namespace TestProject { /// <summary> /// 애니메이션 스크롤 뷰어 /// </summary> public class AnimationScrollViewer : ScrollViewer { //////////////////////////////////////////////////////////////////////////////////////////////////// Dependency Property ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 현재 수평 오프셋 속성 - CurrentHorizontalOffsetProperty /// <summary> /// 현재 수평 오프셋 속성 /// </summary> public static DependencyProperty CurrentHorizontalOffsetProperty = DependencyProperty.Register ( "CurrentHorizontalOffsetOffset", typeof(double), typeof(AnimationScrollViewer), new PropertyMetadata(new PropertyChangedCallback(CurrentHorizontalOffsetPropertyChangedCallback)) ); #endregion #region 현재 수직 오프셋 속성 - CurrentVerticalOffsetProperty /// <summary> /// 현재 수직 오프셋 속성 /// </summary> public static DependencyProperty CurrentVerticalOffsetProperty = DependencyProperty.Register ( "CurrentVerticalOffset", typeof(double), typeof(AnimationScrollViewer), new PropertyMetadata(new PropertyChangedCallback(CurrentVerticalOffsetPropertyChangedCallBack)) ); #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 현재 수평 오프셋 - CurrentHorizontalOffset /// <summary> /// 현재 수평 오프셋 /// </summary> public double CurrentHorizontalOffset { get { return (double)GetValue(CurrentHorizontalOffsetProperty); } set { SetValue(CurrentHorizontalOffsetProperty, value); } } #endregion #region 현재 수직 오프셋 - CurrentVerticalOffset /// <summary> /// 현재 수직 오프셋 /// </summary> public double CurrentVerticalOffset { get { return (double)GetValue(CurrentVerticalOffsetProperty); } set { SetValue(CurrentVerticalOffsetProperty, value); } } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 현재 수평 오프셋 속성 변경시 콜백 처리하기 - CurrentHorizontalOffsetPropertyChangedCallback(d, e) /// <summary> /// 현재 수평 오프셋 속성 변경시 콜백 처리하기 /// </summary> /// <param name="d">의존 객체</param> /// <param name="e">이벤트 인자</param> private static void CurrentHorizontalOffsetPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { AnimationScrollViewer viewer = d as AnimationScrollViewer; viewer.ScrollToHorizontalOffset((double)e.NewValue); } #endregion #region 현재 수직 오프셋 속성 변경시 콜백 처리하기 - CurrentVerticalOffsetPropertyChangedCallBack(d, e) /// <summary> /// 현재 수직 오프셋 속성 변경시 콜백 처리하기 /// </summary> /// <param name="d">의존 객체</param> /// <param name="e">이벤트 인자</param> private static void CurrentVerticalOffsetPropertyChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e) { AnimationScrollViewer viewer = d as AnimationScrollViewer; viewer.ScrollToVerticalOffset((double)e.NewValue); } #endregion } } |
▶ MainWindow.xaml
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 32 33 34 35 36 37 38 |
<Window x:Class="TestProject.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:TestProject" Width="800" Height="600" Title="ScrollViewer 클래스 : 애니메이션 스크롤 뷰어 사용하기" FontFamily="나눔고딕코딩" FontSize="16"> <Grid Margin="10"> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <local:AnimationScrollViewer x:Name="animationScrollViewer" Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> <StackPanel Name="contentStackPanel" /> </local:AnimationScrollViewer> <StackPanel Grid.Row="1" Margin="0 10 0 0" HorizontalAlignment="Right" Orientation="Horizontal"> <ComboBox Name="targetComboBox" VerticalAlignment="Center" Width="150" Height="25" /> <Button Name="animateButton" Margin="10 0 0 0" VerticalAlignment="Center" Width="150" Height="30" Content="애니메이션 시작" /> </StackPanel> </Grid> </Window> |
▶ MainWindow.xaml.cs
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
using System; using System.Windows; using System.Windows.Controls; using System.Windows.Media.Animation; namespace TestProject { /// <summary> /// 메인 윈도우 /// </summary> public partial class MainWindow : Window { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 항목 카운트 /// </summary> private const int ITEM_COUNT = 50; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - MainWindow() /// <summary> /// 생성자 /// </summary> public MainWindow() { InitializeComponent(); for(int i = 0; i < ITEM_COUNT; i++) { Button button = CreateButton(i); ListViewItem item = new ListViewItem(); item.Tag = button; item.Content = "버튼 " + i.ToString(); this.targetComboBox.Items.Add(item); this.contentStackPanel.Children.Add(button); this.animateButton.Click += animateButton_Click; } } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Private //////////////////////////////////////////////////////////////////////////////// Event #region 애니메이션 시작 버튼 클릭시 처리하기 - animateButton_Click(sender, e) /// <summary> /// 애니메이션 시작 버튼 클릭시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void animateButton_Click(object sender, RoutedEventArgs e) { Button button = ((ListViewItem)this.targetComboBox.SelectedItem).Tag as Button; Point relativePoint = button.TransformToAncestor(this.contentStackPanel).Transform(new Point(0, 0)); ScrollToPosition(relativePoint.X, relativePoint.Y); } #endregion //////////////////////////////////////////////////////////////////////////////// Function #region 버튼 생성하기 - CreateButton(index) /// <summary> /// 버튼 생성하기 /// </summary> /// <param name="index">인덱스</param> /// <returns>버튼</returns> private Button CreateButton(int index) { Button button = new Button(); button.Margin = new Thickness(5); button.Height = 30; button.Content = "버튼 " + index.ToString(); return button; } #endregion #region 위치까지 스크롤하기 - ScrollToPosition(x, y) /// <summary> /// 위치까지 스크롤하기 /// </summary> /// <param name="x">X</param> /// <param name="y">Y</param> private void ScrollToPosition(double x, double y) { DoubleAnimation xAnimation = new DoubleAnimation(); xAnimation.From = this.animationScrollViewer.HorizontalOffset; xAnimation.To = x; xAnimation.DecelerationRatio = 0.2; xAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(1000)); DoubleAnimation yAnimation = new DoubleAnimation(); yAnimation.From = this.animationScrollViewer.VerticalOffset; yAnimation.To = y; yAnimation.DecelerationRatio = 0.2; yAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(500)); Storyboard storyboard = new Storyboard(); storyboard.Children.Add(xAnimation); storyboard.Children.Add(yAnimation); Storyboard.SetTarget(xAnimation, this.animationScrollViewer); Storyboard.SetTargetProperty(xAnimation, new PropertyPath(AnimationScrollViewer.CurrentHorizontalOffsetProperty)); Storyboard.SetTarget(yAnimation, this.animationScrollViewer); Storyboard.SetTargetProperty(yAnimation, new PropertyPath(AnimationScrollViewer.CurrentVerticalOffsetProperty)); storyboard.Begin(); } #endregion } } |