■ ConnectedAnimation 클래스를 사용해 리스트 페이지와 상세 페이지 사이에서 연결 애니메이션을 만드는 방법을 보여준다.
▶ CustomItem.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 |
using System; using System.Collections.Generic; namespace TestProject { /// <summary> /// 커스텀 항목 /// </summary> public class CustomItem { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 제목 - Title /// <summary> /// 제목 /// </summary> public string Title { get; set; } #endregion #region 이미지 위치 - ImageLocation /// <summary> /// 이미지 위치 /// </summary> public string ImageLocation { get; set; } #endregion #region 조회 수 - ViewCount /// <summary> /// 조회 수 /// </summary> public string ViewCount { get; set; } #endregion #region 좋아요 수 - LikeCount /// <summary> /// 좋아요 수 /// </summary> public string LikeCount { get; set; } #endregion #region 설명 - Description /// <summary> /// 설명 /// </summary> public string Description { get; set; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - CustomItem() /// <summary> /// 생성자 /// </summary> public CustomItem() { } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 리스트 구하기 - GetList() /// <summary> /// 리스트 구하기 /// </summary> /// <returns>리스트</returns> public static List<CustomItem> GetList() { string[] dummyTextArray = new string[] { @"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer id facilisis lectus. Cras nec convallis ante, quis pulvinar tellus. " + @"Integer dictum accumsan pulvinar. Pellentesque eget enim sodales sapien vestibulum consequat.", @"Nullam eget mattis metus. Donec pharetra, tellus in mattis tincidunt, magna ipsum gravida nibh, vitae lobortis ante odio vel quam.", @"Quisque accumsan pretium ligula in faucibus. Mauris sollicitudin augue vitae lorem cursus condimentum quis ac mauris. " + @"Pellentesque quis turpis non nunc pretium sagittis. Nulla facilisi. Maecenas eu lectus ante. Proin eleifend vel lectus non tincidunt. " + @"Fusce condimentum luctus nisi, in elementum ante tincidunt nec.", @"Aenean in nisl at elit venenatis blandit ut vitae lectus. Praesent in sollicitudin nunc. " + @"Pellentesque justo augue, pretium at sem lacinia, scelerisque semper erat. Ut cursus tortor at metus lacinia dapibus.", @"Ut consequat magna luctus justo egestas vehicula. Integer pharetra risus libero, et posuere justo mattis et.", @"Proin malesuada, libero vitae aliquam venenatis, diam est faucibus felis, vitae efficitur erat nunc non mauris. Suspendisse at sodales erat.", @"Aenean vulputate, turpis non tincidunt ornare, metus est sagittis erat, id lobortis orci odio eget quam. " + @"Suspendisse ex purus, lobortis quis suscipit a, volutpat vitae turpis.", @"Duis facilisis, quam ut laoreet commodo, elit ex aliquet massa, non varius tellus lectus et nunc. Donec vitae risus ut ante pretium semper. " + @"Phasellus consectetur volutpat orci, eu dapibus turpis. Fusce varius sapien eu mattis pharetra.", }; Random random = new Random(); const int locationCount = 8; List<CustomItem> list = new List<CustomItem>(); for(int i = 0; i < locationCount; i++) { list.Add ( new CustomItem() { Title = $"항목 {i + 1}", ImageLocation = $"/IMAGE/sample{i + 1}.jpg", ViewCount = random.Next(100, 999).ToString(), LikeCount = random.Next(10, 99).ToString(), Description = dummyTextArray[i % dummyTextArray.Length] } ); } return list; } #endregion } } |
▶ ListPage.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 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 |
<Page x:Class="TestProject.ListPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:TestProject" FontFamily="나눔고딕코딩" FontSize="16"> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <ListView Name="listView" IsItemClickEnabled="True" SelectionMode="None" Loaded="listView_Loaded" ItemClick="listView_ItemClick"> <ListView.ItemTemplate> <DataTemplate x:DataType="local:CustomItem"> <Grid Margin="0 10 0 10"> <Grid.ColumnDefinitions> <ColumnDefinition MinWidth="150" Width="Auto" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Image Name="image" Grid.Column="0" MaxHeight="100" Stretch="Fill" Source="{x:Bind ImageLocation}" /> <StackPanel Grid.Column="1" Margin="10 0 0 0"> <TextBlock Style="{ThemeResource SubtitleTextBlockStyle}" HorizontalAlignment="Left" Margin="0 0 0 5" Text="{x:Bind Title}" /> <StackPanel Orientation="Horizontal"> <TextBlock Style="{ThemeResource CaptionTextBlockStyle}" FontWeight="Bold" Text="조회 : " /> <TextBlock Style="{ThemeResource CaptionTextBlockStyle}" Margin="5 0 0 0" Text="{x:Bind ViewCount}" /> </StackPanel> <StackPanel Orientation="Horizontal"> <TextBlock Style="{ThemeResource CaptionTextBlockStyle}" FontWeight="Bold" Text="좋아요 : " /> <TextBlock Style="{ThemeResource CaptionTextBlockStyle}" Margin="5 0 0 0" Text="{x:Bind LikeCount}" /> </StackPanel> <StackPanel Orientation="Horizontal"> <TextBlock Style="{ThemeResource BodyTextBlockStyle}" Margin="0 10 0 0" MaxWidth="500" TextTrimming="CharacterEllipsis" MaxLines="1" FontStyle="Italic" Text="{x:Bind Description}" /> </StackPanel> </StackPanel> </Grid> </DataTemplate> </ListView.ItemTemplate> </ListView> </Grid> </Page> |
▶ ListPage.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 |
using System; using Windows.Foundation.Metadata; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media.Animation; using Windows.UI.Xaml.Navigation; namespace TestProject { /// <summary> /// 리스트 페이지 /// </summary> public sealed partial class ListPage : Page { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 커스텀 항목 /// </summary> private CustomItem customItem; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - ListPage() /// <summary> /// 생성자 /// </summary> public ListPage() { this.InitializeComponent(); NavigationCacheMode = NavigationCacheMode.Enabled; this.listView.ItemsSource = CustomItem.GetList(); } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Private #region 리스트 뷰 로드시 처리하기 - listView_Loaded(sender, e) /// <summary> /// 리스트 뷰 로드시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private async void listView_Loaded(object sender, RoutedEventArgs e) { if(this.customItem != null) { this.listView.ScrollIntoView(this.customItem, ScrollIntoViewAlignment.Default); this.listView.UpdateLayout(); ConnectedAnimation animation = ConnectedAnimationService.GetForCurrentView().GetAnimation("BackwardAnimation"); if(animation != null) { if(ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 7)) { animation.Configuration = new DirectConnectedAnimationConfiguration(); } await this.listView.TryStartConnectedAnimationAsync(animation, this.customItem, "image"); } } } #endregion #region 리스트 뷰 항목 클릭시 처리하기 - listView_ItemClick(sender, e) /// <summary> /// 리스트 뷰 항목 클릭시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void listView_ItemClick(object sender, ItemClickEventArgs e) { if(this.listView.ContainerFromItem(e.ClickedItem) is ListViewItem listViewitem) { this.customItem = listViewitem.Content as CustomItem; ConnectedAnimation animation = this.listView.PrepareConnectedAnimation("ForwardAnimation", this.customItem, "image"); } Frame.Navigate(typeof(DetailPage), this.customItem, new SuppressNavigationTransitionInfo()); } #endregion } } |
▶ DetailPage.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 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 |
<Page x:Class="TestProject.DetailPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" FontFamily="나눔고딕코딩" FontSize="16"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Grid Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="{ThemeResource SystemControlAcrylicElementBrush}"> <Button HorizontalAlignment="Left" VerticalAlignment="Top" Background="{ThemeResource SystemAccentColor}" Content="돌아가기" Click="backButton_Click" /> </Grid> <Grid Name="headerContent" Grid.Row="0" Margin="20 50 20 20"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Image Name="image" Grid.Column="0" VerticalAlignment="Top" MaxHeight="400" Stretch="Uniform" Source="{x:Bind CustomItem.ImageLocation}" /> <StackPanel Name="stackPanel" Grid.Column="1" VerticalAlignment="Top" Margin="20 0"> <TextBlock Style="{ThemeResource SubheaderTextBlockStyle}" Margin="0 0 0 10" Text="{x:Bind CustomItem.Title}" /> <StackPanel Orientation="Horizontal"> <TextBlock Style="{ThemeResource SubtitleTextBlockStyle}" FontWeight="Bold" Text="조회 : " /> <TextBlock Style="{ThemeResource SubtitleTextBlockStyle}" Margin="5 0 0 0" Text="{x:Bind CustomItem.ViewCount}" /> </StackPanel> <StackPanel Orientation="Horizontal"> <TextBlock Style="{ThemeResource SubtitleTextBlockStyle}" FontWeight="Bold" Text="좋아요 : " /> <TextBlock Style="{ThemeResource SubtitleTextBlockStyle}" Margin="5 0 0 0" Text="{x:Bind CustomItem.LikeCount}" /> </StackPanel> </StackPanel> </Grid> <Grid Grid.Row="1" Margin="10"> <TextBlock Style="{ThemeResource SubtitleTextBlockStyle}" Text="{x:Bind CustomItem.Description}" /> </Grid> </Grid> </Page> |
▶ DetailPage.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 |
using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Navigation; using Windows.UI.Xaml.Media.Animation; namespace TestProject { /// <summary> /// 상세 페이지 /// </summary> public sealed partial class DetailPage : Page { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 커스텀 항목 - CustomItem /// <summary> /// 커스텀 항목 /// </summary> public CustomItem CustomItem { get; set; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - DetailPage() /// <summary> /// 생성자 /// </summary> public DetailPage() { InitializeComponent(); } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Protected #region 탐색되는 경우 처리하기 - OnNavigatedTo(e) /// <summary> /// 탐색되는 경우 처리하기 /// </summary> /// <param name="e">이벤트 인자</param> protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); CustomItem = e.Parameter as CustomItem; ConnectedAnimation animation = ConnectedAnimationService.GetForCurrentView().GetAnimation("ForwardAnimation"); if(animation != null) { animation.TryStart(this.image, new UIElement[] { this.stackPanel }); } } #endregion #region 탐색하는 경우 처리하기 - OnNavigatingFrom(e) /// <summary> /// 탐색하는 경우 처리하기 /// </summary> /// <param name="e">이벤트 인자</param> protected override void OnNavigatingFrom(NavigatingCancelEventArgs e) { base.OnNavigatingFrom(e); ConnectedAnimationService.GetForCurrentView().PrepareToAnimate("BackwardAnimation", this.image); } #endregion ////////////////////////////////////////////////////////////////////////////////////////// Private #region 돌아가기 버튼 클릭시 처리하기 - backButton_Click(sender, e) /// <summary> /// 돌아가기 버튼 클릭시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void backButton_Click(object sender, RoutedEventArgs e) { Frame.GoBack(); } #endregion } } |
▶ MainPage.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<Page x:Class="TestProject.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" FontFamily="나눔고딕코딩" FontSize="16"> <Grid> <Frame Name="frame" Margin="10" /> </Grid> </Page> |
▶ MainPage.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 |
using Windows.Foundation; using Windows.Graphics.Display; using Windows.UI.ViewManagement; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; namespace TestProject { /// <summary> /// 메인 페이지 /// </summary> public sealed partial class MainPage : Page { //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - MainPage() /// <summary> /// 생성자 /// </summary> public MainPage() { InitializeComponent(); #region 윈도우 크기를 설정한다. double width = 800d; double height = 600d; double dpi = (double)DisplayInformation.GetForCurrentView().LogicalDpi; ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize; Size windowSize = new Size(width * 96d / dpi, height * 96d / dpi); ApplicationView.PreferredLaunchViewSize = windowSize; Window.Current.Activate(); ApplicationView.GetForCurrentView().TryResizeView(windowSize); #endregion #region 윈도우 제목을 설정한다. ApplicationView.GetForCurrentView().Title = "ConnectedAnimation 클래스 : 리스트 페이지와 상세 페이지 사이에서 연결 애니메이션 사용하기"; #endregion this.frame.Navigate(typeof(ListPage)); } #endregion } } |