diff --git a/components/Animations/samples/Animations.Samples.csproj b/components/Animations/samples/Animations.Samples.csproj index 10a9ebbe..8a745515 100644 --- a/components/Animations/samples/Animations.Samples.csproj +++ b/components/Animations/samples/Animations.Samples.csproj @@ -5,4 +5,36 @@ + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + diff --git a/components/Animations/samples/AnimationsImplicitSample.xaml b/components/Animations/samples/AnimationsImplicitSample.xaml index 37bb2880..d9d80ed9 100644 --- a/components/Animations/samples/AnimationsImplicitSample.xaml +++ b/components/Animations/samples/AnimationsImplicitSample.xaml @@ -1,4 +1,4 @@ - + - + - + @@ -20,7 +19,8 @@ Canvas.Top="100" Width="100" Height="100" - Background="{ThemeResource AccentFillColorDefaultBrush}"> + Background="{ThemeResource AccentFillColorDefaultBrush}" + CornerRadius="{StaticResource ControlCornerRadius}"> [!Sample ConnectedAnimationsSample] + +## Syntax + +```xaml + + + + + + + + + + + + + + +``` + +## XAML Attached Properties + +### Connected.Key + +Registers element with the [ConnectedAnimationsService](/uwp/api/Windows.UI.Xaml.Media.Animation.ConnectedAnimation). For the animation to work, the same key must be registered on two different pages when navigating + +### Connected.AnchorElement + +To enable [coordinated animations](/windows/uwp/style/connected-animation#coordinated-animation), use the AnchorElement attached property on the element that should appear alongside the connected animation element by specifying the connected animation element + +### Connected.ListItemKey + +Registers a ListView/GridView for connected animations. When navigating from/to a page that is using this property, the connected animation will use the item passed as a **parameter** in the page navigation to select the item in the list that should animated. See *Select List Item to be animated* section below for more details. The *Connected.ListItemElementName* attached property must also be set for the animation to be registered + +### Connected.ListItemElementName + +Specifies what named element in the DataTemplate of an item should animate. The Connected.ListItemKey attached property must also be set for the animation to be registered. + +## Registering elements in code behind + +In cases where an element has not loaded before the navigation completes, the attached properties are not able to access the element properties to register it for the connected animation. In those case, you can register the element through code behind inside the OnNavigatedTo method. The following extension methods are available: + +### RegisterElementForConnectedAnimation(this Page page, string key, UIElement element, IEnumerable\ anchors = null) + +Registers a UIElement with the ConnectedAnimations service to run automatically on page navigation + +### UnregisterElementForConnectedAnimation(this Page page, string key) + +Unregisters a UIElement from the ConnectedAnimations service + +### AttachAnchorElementForConnectedAnimation(this Page page, UIElement element, UIElement anchor) + +Add an anchor element to animate alongside the main element + +### RemoveAnchoredElementForConnectedAnimation(this Page page, UIElement element, UIElement anchor) + +Remove an anchor element from animating alongside the main element + +### RegisterListItemForConnectedAnimation(this Page page, ListViewBase listViewBase, string key, string elementName) + +Registers an element (part of a DataTemplate in a list control) with the ConnectedAnimations service to run automatically on page navigation + +### UnregisterListItemForConnectedAnimation(this Page page, ListViewBase listViewBase, string key) + +Unregisters an element (part of a DataTemplate in a list control) from the ConnectedAnimations service + +## Select List Item to be animated + +The helper uses the page navigation parameter to decide which list item will be animated during the page navigation. However, in some cases the parameter passed during page navigation is not part of the list. For example, you might be only passing the id of an item as a navigation parameter and not the item itself. + +In those cases, you can use the **SetListDataItemForNextConnectedAnnimation** extension method before page navigation to specify which item should be animated. + +```csharp + // dataItemToAnimate is an object in the ListViewBase.ItemsSource collection + Frame.SetListDataItemForNextConnectedAnnimation(dataItemToAnimate); + Frame.Navigate(typeof(DetailsPage), dataItemToAnimate.Id); +``` + +```vb + ' dataItemToAnimate is an object in the ListViewBase.ItemsSource collection + Frame.SetListDataItemForNextConnectedAnnimation(dataItemToAnimate) + Frame.Navigate(GetType(DetailsPage), dataItemToAnimate.Id) +``` + +This method is also helpful when navigating back to an item different from the item it was navigated from. + +```csharp + Frame.SetListDataItemForNextConnectedAnnimation(dataItemToAnimate); + Frame.GoBack(); +``` + +```vb + Frame.SetListDataItemForNextConnectedAnnimation(dataItemToAnimate) + Frame.GoBack() +``` + +## Examples + +We can create the above connected animations. + +### In first page + +We need a set a key for the element to be connected with another element in a different page. + +```xaml + + + +``` + +### In second page + +We need to set the same key for the element to be connected with. Also, You can anchor another element to move along the connected animation path. + +```xaml + + + + + Header + Lorem ipsum ... + + +``` + +In this page, we can also create a GridView which implements connected animation for its items. You need to set ListItemKey and ListItemElementName for specifying the UIElement to animate. + +```xaml + + + + + + + + + + +``` + +### In third page + +In this page, you just need to give the same key. + +```xaml + + + + + Lorem ipsum ... + + + + + + Lorem Ipsum ... + +``` + diff --git a/components/Animations/samples/ConnectedAnimations/FirstPage.xaml b/components/Animations/samples/ConnectedAnimations/FirstPage.xaml new file mode 100644 index 00000000..1c0f8e91 --- /dev/null +++ b/components/Animations/samples/ConnectedAnimations/FirstPage.xaml @@ -0,0 +1,27 @@ + + + + + + + + + diff --git a/components/Animations/samples/ConnectedAnimations/FirstPage.xaml.cs b/components/Animations/samples/ConnectedAnimations/FirstPage.xaml.cs new file mode 100644 index 00000000..c5802f77 --- /dev/null +++ b/components/Animations/samples/ConnectedAnimations/FirstPage.xaml.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace AnimationsExperiment.Samples.ConnectedAnimations; + + public sealed partial class FirstPage : Page +{ + public FirstPage() + { + this.InitializeComponent(); + } + + private void Border_Tapped(object sender, TappedRoutedEventArgs e) + { + Frame.Navigate(typeof(SecondPage), null, new SuppressNavigationTransitionInfo()); + } +} diff --git a/components/Animations/samples/ConnectedAnimations/SecondPage.xaml b/components/Animations/samples/ConnectedAnimations/SecondPage.xaml new file mode 100644 index 00000000..0a0dc382 --- /dev/null +++ b/components/Animations/samples/ConnectedAnimations/SecondPage.xaml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/Animations/samples/ConnectedAnimations/SecondPage.xaml.cs b/components/Animations/samples/ConnectedAnimations/SecondPage.xaml.cs new file mode 100644 index 00000000..28629a0e --- /dev/null +++ b/components/Animations/samples/ConnectedAnimations/SecondPage.xaml.cs @@ -0,0 +1,76 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace AnimationsExperiment.Samples.ConnectedAnimations; + +public sealed partial class SecondPage : Page +{ + private static ObservableCollection? items; + + public SecondPage() + { + this.InitializeComponent(); + } + + private void ListView_ItemClick(object sender, ItemClickEventArgs e) + { + Frame.Navigate(typeof(ThirdPage), e.ClickedItem, new SuppressNavigationTransitionInfo()); + } + + protected override void OnNavigatedTo(NavigationEventArgs e) + { + base.OnNavigatedTo(e); + + if (items == null) + { + items = new ObservableCollection + { + new PhotoDataItem + { + Title = "Big Four Summer Heat", + Thumbnail = "ms-appx:///Assets/BigFourSummerHeat2.jpg", + }, + new PhotoDataItem + { + Title = "Bison Badlands Chillin", + Thumbnail = "ms-appx:///Assets/BisonBadlandsChillin2.jpg", + }, + new PhotoDataItem + { + Title = "Columbia River Gorge", + Thumbnail = "ms-appx:///Assets/ColumbiaRiverGorge.jpg", + }, + new PhotoDataItem + { + Title = "Grand Tetons", + Thumbnail = "ms-appx:///Assets/GrandTetons.jpg", + }, + new PhotoDataItem + { + Title = "Oregon Winery Namaste", + Thumbnail = "ms-appx:///Assets/OregonWineryNamaste.jpg", + }, + new PhotoDataItem + { + Title = "Running Dog Pacific City", + Thumbnail = "ms-appx:///Assets/RunningDogPacificCity.jpg", + } + }; + } + + listView.ItemsSource = items; + } +} + +public class PhotoDataItem +{ + public string? Title { get; set; } + + public string? Thumbnail { get; set; } + + public override string ToString() + { + return Title!; + } +} diff --git a/components/Animations/samples/ConnectedAnimations/ThirdPage.xaml b/components/Animations/samples/ConnectedAnimations/ThirdPage.xaml new file mode 100644 index 00000000..3077f002 --- /dev/null +++ b/components/Animations/samples/ConnectedAnimations/ThirdPage.xaml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + diff --git a/components/Animations/samples/ConnectedAnimations/ThirdPage.xaml.cs b/components/Animations/samples/ConnectedAnimations/ThirdPage.xaml.cs new file mode 100644 index 00000000..c319f223 --- /dev/null +++ b/components/Animations/samples/ConnectedAnimations/ThirdPage.xaml.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace AnimationsExperiment.Samples.ConnectedAnimations; + +public sealed partial class ThirdPage : Page +{ + private PhotoDataItem item = new(); + + public ThirdPage() + { + this.InitializeComponent(); + } + + protected override void OnNavigatedTo(NavigationEventArgs e) + { + if (e.Parameter is PhotoDataItem photoItem) + { + item = photoItem; + } + + base.OnNavigatedTo(e); + } +} diff --git a/components/Animations/samples/ConnectedAnimationsSample.xaml b/components/Animations/samples/ConnectedAnimationsSample.xaml new file mode 100644 index 00000000..6d2bf0a2 --- /dev/null +++ b/components/Animations/samples/ConnectedAnimationsSample.xaml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/Animations/samples/ConnectedAnimationsSample.xaml.cs b/components/Animations/samples/ConnectedAnimationsSample.xaml.cs new file mode 100644 index 00000000..30c94cb7 --- /dev/null +++ b/components/Animations/samples/ConnectedAnimationsSample.xaml.cs @@ -0,0 +1,37 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using AnimationsExperiment.Samples.ConnectedAnimations; + +namespace AnimationsExperiment.Samples; + +[ToolkitSample(id: nameof(ConnectedAnimationsSample), "Connected Animations", description: $"A sample for showing how to create and use connected animations.")] +public sealed partial class ConnectedAnimationsSample : Page +{ + + public ConnectedAnimationsSample() + { + this.InitializeComponent(); + + RootFrame.Navigate(typeof(FirstPage)); + } + + private void Frame_Navigated(object sender, NavigationEventArgs e) + { + BackButton.Visibility = RootFrame.CanGoBack ? Visibility.Visible : Visibility.Collapsed; + } + + private void RootFrame_Navigating(object sender, NavigatingCancelEventArgs e) + { + if (e.SourcePageType == RootFrame.SourcePageType) + { + e.Cancel = true; + } + } + + private void BackButton_Click(object sender, RoutedEventArgs e) + { + RootFrame.GoBack(new SuppressNavigationTransitionInfo()); + } +}