Uwp 可折叠页眉

Uwp 可折叠页眉,uwp,win-universal-app,windows-10-universal,uwp-xaml,windows-composition-api,Uwp,Win Universal App,Windows 10 Universal,Uwp Xaml,Windows Composition Api,我正在尝试实现可折叠的页眉。主要思想是我必须根据scrollviewer中的更改来更改页眉的高度(最小高度60,最大高度160) 这是我想要达到的结果 页面标题的初始状态 向下滚动时的页眉 我的XAML代码: <controls:CollapsablePageHeader> <controls:CollapsablePageHeader> <Grid x:Name="CollapsablePageHeaderGri

我正在尝试实现可折叠的页眉。主要思想是我必须根据
scrollviewer
中的更改来更改页眉的高度(最小高度60,最大高度160)

这是我想要达到的结果

页面标题的初始状态

向下滚动时的页眉

我的XAML代码:

    <controls:CollapsablePageHeader>
        <controls:CollapsablePageHeader>
            <Grid x:Name="CollapsablePageHeaderGrid" MinHeight="150" Background="{StaticResource ApplicationAccentBackgroundColorBrush}">
                <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="25 905" HorizontalAlignment="Center" FontSize="50" Foreground="{StaticResource ApplicationAlternativeAccentColorBrush}"/>
                        <controls:TengeSignControl FontSize="50" Foreground="{StaticResource ApplicationAlternativeAccentColorBrush}"/>
                    </StackPanel>
                    <StackPanel Orientation="Horizontal">
                        <Image Source="/Assets/CreditCard.png" Height="20" Width="20" Margin="0,5,5,0"/>
                        <TextBlock Text="Bank of Arkham City" FontSize="{StaticResource BigTextSize}" Foreground="{StaticResource ApplicationAlternativeAccentColorBrush}"/>
                    </StackPanel>
                </StackPanel>
            </Grid>
        </controls:CollapsablePageHeader>
    </controls:CollapsablePageHeader>
    <ScrollViewer x:Name="MainScrollViewer" Grid.Row="1" IsTabStop="False" ScrollViewer.HorizontalScrollMode="Disabled" ScrollViewer.VerticalScrollBarVisibility="Hidden">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <!--Layout for user favorite payment templates-->
            <toolkitControls:DropShadowPanel Style="{StaticResource DefaultCardDropShadowEffect}">
                <Grid Style="{StaticResource CardConontrolElement}">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <TextBlock x:Uid="Favorites" Style="{StaticResource SectionHeaderTextBlock}" HorizontalAlignment="Left" />
                    <GridView x:Name="UserTemplatesSelector" Grid.Row="1" ItemsSource="{Binding PaymentTemplates}" ItemTemplate="{StaticResource UserTemplatesDataTemplate}" Margin="-10,0,-10,0" Padding="10,0,0,0" Style="{StaticResource DefaultHorizontalGridView}" ItemContainerStyle="{StaticResource DefaultHorizontalGridViewItemContainer}">
                        <GridView.ItemsPanel>
                            <ItemsPanelTemplate>
                                <StackPanel Orientation="Horizontal"/>
                            </ItemsPanelTemplate>
                        </GridView.ItemsPanel>
                    </GridView>
                </Grid>
            </toolkitControls:DropShadowPanel>
            <!-- Layout for last operations -->
            <toolkitControls:DropShadowPanel Grid.Row="1" Margin="0,20,0,0" Style="{StaticResource DefaultCardDropShadowEffect}">
                <Grid Style="{StaticResource CardConontrolElement}">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <TextBlock x:Uid="LastOperations" Style="{StaticResource SectionHeaderTextBlock}"/>
                    <ListView x:Name="LastOperationsListView" Grid.Row="1" ItemsSource="{Binding LastTransactions}" ItemTemplate="{StaticResource LastOperationsDataTemplate}" Margin="0,10,0,0" ItemContainerStyle="{StaticResource DefaultListViewItemContainer}"/>
                    <Button x:Name="ShowMoreOperationsButton" Content="Показать всё" Grid.Row="2" Style="{StaticResource TiltableAccentButton}"/>
                </Grid>
            </toolkitControls:DropShadowPanel>
            <!-- Layour for bound cards -->
            <toolkitControls:DropShadowPanel Grid.Row="2" Margin="0,20" Style="{StaticResource DefaultCardDropShadowEffect}">
                <Grid Style="{StaticResource CardConontrolElement}">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <TextBlock x:Uid="LastOperations" Style="{StaticResource SectionHeaderTextBlock}" Typography.Capitals="AllSmallCaps"/>
                    <ListView x:Name="BoundCardListView" Grid.Row="1" ItemsSource="{Binding BoundCards}" ItemTemplate="{StaticResource BoundCardsDataTemplate}" Margin="0,10,0,0" ItemContainerStyle="{StaticResource DefaultListViewItemContainer}"/>
                    <Button x:Name="ShowMoreCardsButton" Content="Показать всё" Grid.Row="2" Style="{StaticResource TiltableAccentButton}"/>
                </Grid>
            </toolkitControls:DropShadowPanel>
        </Grid>
    </ScrollViewer>`
头服务启动时异常

System.ArgumentException: 'The parameter is incorrect.The animation failed to connect.'
更新的xaml:

 <Grid x:Name="LayoutRoot" Style="{StaticResource DefaultLayoutRootStyle}">
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>

    <ScrollViewer x:Name="MainScrollViewer" IsTabStop="False" ScrollViewer.HorizontalScrollMode="Disabled" ScrollViewer.VerticalScrollBarVisibility="Hidden">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>

            <Grid x:Name="CollapsiblePageHeader" Height="150" VerticalAlignment="Top">
                <ScrollViewer>
                    <Grid>
                        <Rectangle Height="300" HorizontalAlignment="Left" VerticalAlignment="Top">
                            <Rectangle.Fill>
                                <ImageBrush ImageSource="ms-appx:///Assets/Samples/SampleParallaxImage.jpg"/>
                            </Rectangle.Fill>
                        </Rectangle>
                        <StackPanel>
                            <StackPanel x:Name="TitleContainer" VerticalAlignment="Top" HorizontalAlignment="Center" Orientation="Horizontal">
                                <TextBlock x:Name="TitleText" Text="25 905" FontSize="50" Foreground="{StaticResource ApplicationAlternativeAccentColorBrush}"/>
                                <controls:TengeSignControl x:Name="TitleImage" FontSize="50" Foreground="{StaticResource ApplicationAlternativeAccentColorBrush}"/>
                            </StackPanel>
                            <StackPanel x:Name="SubtitleContainer" HorizontalAlignment="Center" VerticalAlignment="Top" Grid.Row="1" Orientation="Horizontal">
                                <Image x:Name="SubtitleImage" Source="/Assets/CreditCard.png" Height="20" Width="20" Margin="0,5,5,0"/>
                                <TextBlock x:Name="SubtitleText" Text="Bank of Arkham City" FontSize="{StaticResource BigTextSize}" Foreground="{StaticResource ApplicationAlternativeAccentColorBrush}"/>
                            </StackPanel>
                        </StackPanel>
                    </Grid>
                </ScrollViewer>
            </Grid>

            <Grid Grid.Row="1">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>

                <!--Layout for user favorite payment templates-->
                <toolkitControls:DropShadowPanel Grid.Row="1" Style="{StaticResource DefaultCardDropShadowEffect}">
                    <Grid Style="{StaticResource CardConontrolElement}">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                        </Grid.RowDefinitions>
                        <TextBlock x:Uid="Favorites" Style="{StaticResource SectionHeaderTextBlock}" HorizontalAlignment="Left" />
                        <GridView x:Name="UserTemplatesSelector" Grid.Row="1" ItemsSource="{Binding PaymentTemplates}" ScrollViewer.HorizontalScrollMode="Enabled" ScrollViewer.VerticalScrollMode="Disabled" ItemTemplate="{StaticResource UserTemplatesDataTemplate}" Margin="-10,0,-10,0" Padding="10,0,0,0" Style="{StaticResource DefaultGridView}" ItemContainerStyle="{StaticResource DefaultGridViewItemContainer}"/>
                    </Grid>
                </toolkitControls:DropShadowPanel>

                <!-- Layout for last operations -->
                <toolkitControls:DropShadowPanel Grid.Row="2" Margin="0,20,0,0" Style="{StaticResource DefaultCardDropShadowEffect}">
                    <Grid Style="{StaticResource CardConontrolElement}">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                        </Grid.RowDefinitions>
                        <TextBlock x:Uid="LastOperations" Style="{StaticResource SectionHeaderTextBlock}"/>
                        <ListView x:Name="LastOperationsListView" Grid.Row="1"  ScrollViewer.VerticalScrollMode="Disabled"  ItemsSource="{Binding LastTransactions}" ItemTemplate="{StaticResource LastOperationsDataTemplate}" Margin="0,10,0,0" ItemContainerStyle="{StaticResource DefaultListViewItemContainer}"/>
                        <Button x:Name="ShowMoreOperationsButton" Content="Показать всё" Grid.Row="2" Style="{StaticResource TiltableAccentButton}"/>
                    </Grid>
                </toolkitControls:DropShadowPanel>

                <!-- Layour for bound cards -->
                <toolkitControls:DropShadowPanel Grid.Row="3" Margin="0,20" Style="{StaticResource DefaultCardDropShadowEffect}">
                    <Grid Style="{StaticResource CardConontrolElement}">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                        </Grid.RowDefinitions>
                        <TextBlock Text="Привязанные карты" Style="{StaticResource SectionHeaderTextBlock}" Typography.Capitals="AllSmallCaps"/>
                        <ListView x:Name="BoundCardListView" Grid.Row="1" ScrollViewer.VerticalScrollMode="Disabled" ItemsSource="{Binding BoundCards}" ItemTemplate="{StaticResource BoundCardsDataTemplate}" Margin="0,10,0,0" ItemContainerStyle="{StaticResource DefaultListViewItemContainer}"/>
                        <Button x:Name="ShowMoreCardsButton" Content="Показать всё" Grid.Row="2" Style="{StaticResource TiltableAccentButton}"/>
                    </Grid>
                </toolkitControls:DropShadowPanel>
            </Grid>
        </Grid>
    </ScrollViewer>

    <CommandBar x:Name="PaymentOperations" Grid.Row="1">
        <AppBarButton x:Name="VendorPayment" Label="Оплата поставщиков" Icon="Shop" Click="MerchantPayment_Click"/>
        <AppBarButton x:Name="p2pPayment" Label="P2P оплата" Icon="Remote" Click="PersonToPersonPayment_Click"/>
        <AppBarButton x:Name="w2wPayment" Label="Перевод с кошелька на кошелек" Icon="Manage" Click="WalletToWalletPayment_Click"/>
    </CommandBar>
</Grid>

完整的xaml.cs:

    private void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        // Get the PropertySet that contains the scroll values from MyScrollViewer
        _scrollerPropertySet = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(MainScrollViewer);
        _compositor = _scrollerPropertySet.Compositor;

        // Create a PropertySet that has values to be referenced in the ExpressionAnimations below
        _props = _compositor.CreatePropertySet();
        _props.InsertScalar("progress", 0);
        _props.InsertScalar("clampSize", 150);
        _props.InsertScalar("scaleFactor", 0.7f);

        // Get references to our property sets for use with ExpressionNodes
        var scrollingProperties = _scrollerPropertySet.GetSpecializedReference<ManipulationPropertySetReferenceNode>();
        var props = _props.GetReference();
        var progressNode = props.GetScalarProperty("progress");
        var clampSizeNode = props.GetScalarProperty("clampSize");
        var scaleFactorNode = props.GetScalarProperty("scaleFactor");

        // Create and start an ExpressionAnimation to track scroll progress over the desired distance
        ExpressionNode progressAnimation = EF.Clamp(-scrollingProperties.Translation.Y / clampSizeNode, 0, 1);
        _props.StartAnimation("progress", progressAnimation);

        // Get the backing visual for the header so that its properties can be animated
        Visual headerVisual = ElementCompositionPreview.GetElementVisual(CollapsiblePageHeader);

        // Create and start an ExpressionAnimation to clamp the header's offset to keep it onscreen
        ExpressionNode headerTranslationAnimation = EF.Conditional(progressNode < 1, 0, -scrollingProperties.Translation.Y - clampSizeNode);
        // Works fine
        headerVisual.StartAnimation("Offset.Y", headerTranslationAnimation);

        ExpressionNode headerScaleAnimation = EF.Lerp(1, 1.25f, EF.Clamp(scrollingProperties.Translation.Y / 50, 0, 1));
        // Exception here
        headerVisual.StartAnimation("Scale.X", headerScaleAnimation);
        headerVisual.StartAnimation("Scale.Y", headerScaleAnimation);


        //Set the header's CenterPoint to ensure the overpan scale looks as desired
        headerVisual.CenterPoint = new Vector3((float)(CollapsiblePageHeader.ActualWidth / 2), (float)CollapsiblePageHeader.ActualHeight, 0);

        // Create and start an ExpressionAnimation to scale the profile image with scroll position
        ExpressionNode scaleAnimation = EF.Lerp(1, scaleFactorNode, progressNode);

        // Get backing visuals for the text blocks so that their properties can be animated
        Visual titleVisual = ElementCompositionPreview.GetElementVisual(TitleText);
        Visual titleImageVisual = ElementCompositionPreview.GetElementVisual(TitleImage);
        Visual subtitleVisual = ElementCompositionPreview.GetElementVisual(SubtitleText);
        Visual subtitleImageVisual = ElementCompositionPreview.GetElementVisual(SubtitleImage);

        // Create an ExpressionAnimation that moves between 1 and 0 with scroll progress, to be used for text block opacity
        ExpressionNode textOpacityAnimation = EF.Clamp(1 - (progressNode * 2), 0, 1);

        // Start opacity and scale animations on the text block visuals
        titleVisual.StartAnimation("Scale.X", scaleAnimation);
        titleVisual.StartAnimation("Scale.Y", scaleAnimation);

        titleImageVisual.StartAnimation("Scale.X", scaleAnimation);
        titleImageVisual.StartAnimation("Scale.Y", scaleAnimation);

        subtitleVisual.StartAnimation("Opacity", textOpacityAnimation);
        subtitleVisual.StartAnimation("Scale.X", scaleAnimation);
        subtitleVisual.StartAnimation("Scale.Y", scaleAnimation);

        subtitleImageVisual.StartAnimation("Opacity", textOpacityAnimation);
        subtitleImageVisual.StartAnimation("Scale.X", scaleAnimation);
        subtitleImageVisual.StartAnimation("Scale.Y", scaleAnimation);

        // Get the backing visuals for the text and button containers so that their properites can be animated
        Visual subtitleContainerVisual = ElementCompositionPreview.GetElementVisual(SubtitleContainer);

        // When the header stops scrolling it is 150 pixels offscreen.  We want the text header to end up with 50 pixels of its content
        // offscreen which means it needs to go from offset 0 to 100 as we traverse through the scrollable region
        ExpressionNode contentOffsetAnimation = progressNode * 100;

        subtitleContainerVisual.StartAnimation("Offset.Y", contentOffsetAnimation);
    }
private void主页\u已加载(对象发送方、路由目标方)
{
//从MyScrollViewer获取包含滚动值的属性集
_scrollerPropertySet=ElementCompositionPreview.GetScrollViewerManipulationPropertySet(MainScrollViewer);
_合成器=_scrollerPropertySet.compositor;
//创建一个PropertySet,其中包含要在下面的表达式动画中引用的值
_props=_compositor.CreatePropertySet();
_道具插入标量(“进度”,0);
_插入标量的道具(“clampSize”,150);
_props.InsertScalar(“scaleFactor”,0.7f);
//获取对ExpressionNodes使用的属性集的引用
var scrollingProperties=_scrollerPropertySet.GetSpecializedReference();
var props=_props.GetReference();
var progressNode=props.GetScalarProperty(“进度”);
var clampSizeNode=props.GetScalarProperty(“clampSize”);
var scaleFactorNode=props.GetScalarProperty(“scaleFactor”);
//创建并启动ExpressionAnimation以跟踪所需距离上的滚动进度
ExpressionNode progressAnimation=EF.Clamp(-scrollingProperties.Translation.Y/clampSizeNode,0,1);
_道具。开始动画(“进展”,进展动画);
//获取标题的背景视觉效果,以便对其属性设置动画
VisualHeadServiceSual=ElementCompositionPreview.GetElementVisual(可折叠页眉);
//创建并启动ExpressionAnimation以夹紧标题的偏移量,使其保持在屏幕上
ExpressionNode headerTranslationAnimation=EF.Conditional(progressNode<1,0,-scrollingProperties.Translation.Y-clampSizeNode);
//很好
headerservicesual.StartAnimation(“Offset.Y”,headerTranslationAnimation);
ExpressionNode headerScaleAnimation=EF.Lerp(1,1.25f,EF.Clamp(scrollingProperties.Translation.Y/50,0,1));
//这里例外
headerVisual.StartAnimation(“Scale.X”,headerScaleAnimation);
headerVisual.StartAnimation(“Scale.Y”,headerScaleAnimation);
//设置收割台的中心点,以确保天桥比例符合要求
headerVisual.CenterPoint=新矢量3((浮点)(collappablepageheader.ActualWidth/2),(浮点)collappablepageheader.ActualHeight,0);
//创建并启动ExpressionAnimation以使用滚动位置缩放配置文件图像
ExpressionNode scaleAnimation=EF.Lerp(1,scaleFactorNode,progressNode);
//获取文本块的背景视觉效果,以便为其属性设置动画
Visual titleVisual=ElementCompositionPreview.GetElementVisual(TitleText);
Visual titleImageVisual=ElementCompositionPreview.GetElementVisual(TitleImage);
VisualSubtitleVisual=ElementCompositionPreview.GetElementVisual(SubtitleText);
Visual subtitleImageVisual=ElementCompositionPreview.GetElementVisual(SubtitleImage);
//创建一个在1和0之间随滚动进度移动的表达式动画,用于文本块不透明度
expressionNodeTextOpacityImation=EF.Clamp(1-(progressNode*2),0,1);
//在文本块视觉效果上启动不透明度和缩放动画
titleVisual.StartAnimation(“Scale.X”,scaleAnimation);
titleVisual.StartAnimation(“Scale.Y”,scaleAnimation);
titleImageVisual.StartAnimation(“Scale.X”,scaleAnimation);
titleImageVisual.StartAnimation(“Scale.Y”,scaleAnimation);
字幕视觉。开始图像(“不透明”,文本不透明图像);
字幕视觉。开始动画(“Scale.X”,scaleAnimation);
字幕:视觉。起始动画(“Scale.Y”,scaleAnimation);
字幕ImageVisualy.StartAnimation(“不透明度”),textOpacit
    private void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        // Get the PropertySet that contains the scroll values from MyScrollViewer
        _scrollerPropertySet = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(MainScrollViewer);
        _compositor = _scrollerPropertySet.Compositor;

        // Create a PropertySet that has values to be referenced in the ExpressionAnimations below
        _props = _compositor.CreatePropertySet();
        _props.InsertScalar("progress", 0);
        _props.InsertScalar("clampSize", 150);
        _props.InsertScalar("scaleFactor", 0.7f);

        // Get references to our property sets for use with ExpressionNodes
        var scrollingProperties = _scrollerPropertySet.GetSpecializedReference<ManipulationPropertySetReferenceNode>();
        var props = _props.GetReference();
        var progressNode = props.GetScalarProperty("progress");
        var clampSizeNode = props.GetScalarProperty("clampSize");
        var scaleFactorNode = props.GetScalarProperty("scaleFactor");

        // Create and start an ExpressionAnimation to track scroll progress over the desired distance
        ExpressionNode progressAnimation = EF.Clamp(-scrollingProperties.Translation.Y / clampSizeNode, 0, 1);
        _props.StartAnimation("progress", progressAnimation);

        // Get the backing visual for the header so that its properties can be animated
        Visual headerVisual = ElementCompositionPreview.GetElementVisual(CollapsiblePageHeader);

        // Create and start an ExpressionAnimation to clamp the header's offset to keep it onscreen
        ExpressionNode headerTranslationAnimation = EF.Conditional(progressNode < 1, 0, -scrollingProperties.Translation.Y - clampSizeNode);
        // Works fine
        headerVisual.StartAnimation("Offset.Y", headerTranslationAnimation);

        ExpressionNode headerScaleAnimation = EF.Lerp(1, 1.25f, EF.Clamp(scrollingProperties.Translation.Y / 50, 0, 1));
        // Exception here
        headerVisual.StartAnimation("Scale.X", headerScaleAnimation);
        headerVisual.StartAnimation("Scale.Y", headerScaleAnimation);


        //Set the header's CenterPoint to ensure the overpan scale looks as desired
        headerVisual.CenterPoint = new Vector3((float)(CollapsiblePageHeader.ActualWidth / 2), (float)CollapsiblePageHeader.ActualHeight, 0);

        // Create and start an ExpressionAnimation to scale the profile image with scroll position
        ExpressionNode scaleAnimation = EF.Lerp(1, scaleFactorNode, progressNode);

        // Get backing visuals for the text blocks so that their properties can be animated
        Visual titleVisual = ElementCompositionPreview.GetElementVisual(TitleText);
        Visual titleImageVisual = ElementCompositionPreview.GetElementVisual(TitleImage);
        Visual subtitleVisual = ElementCompositionPreview.GetElementVisual(SubtitleText);
        Visual subtitleImageVisual = ElementCompositionPreview.GetElementVisual(SubtitleImage);

        // Create an ExpressionAnimation that moves between 1 and 0 with scroll progress, to be used for text block opacity
        ExpressionNode textOpacityAnimation = EF.Clamp(1 - (progressNode * 2), 0, 1);

        // Start opacity and scale animations on the text block visuals
        titleVisual.StartAnimation("Scale.X", scaleAnimation);
        titleVisual.StartAnimation("Scale.Y", scaleAnimation);

        titleImageVisual.StartAnimation("Scale.X", scaleAnimation);
        titleImageVisual.StartAnimation("Scale.Y", scaleAnimation);

        subtitleVisual.StartAnimation("Opacity", textOpacityAnimation);
        subtitleVisual.StartAnimation("Scale.X", scaleAnimation);
        subtitleVisual.StartAnimation("Scale.Y", scaleAnimation);

        subtitleImageVisual.StartAnimation("Opacity", textOpacityAnimation);
        subtitleImageVisual.StartAnimation("Scale.X", scaleAnimation);
        subtitleImageVisual.StartAnimation("Scale.Y", scaleAnimation);

        // Get the backing visuals for the text and button containers so that their properites can be animated
        Visual subtitleContainerVisual = ElementCompositionPreview.GetElementVisual(SubtitleContainer);

        // When the header stops scrolling it is 150 pixels offscreen.  We want the text header to end up with 50 pixels of its content
        // offscreen which means it needs to go from offset 0 to 100 as we traverse through the scrollable region
        ExpressionNode contentOffsetAnimation = progressNode * 100;

        subtitleContainerVisual.StartAnimation("Offset.Y", contentOffsetAnimation);
    }