silverlightのナビゲーションコントロールを利用して、ページをめくる効果を実現します


具体的な考え方は次のとおりです.
  • を使用してFrameを回転アニメーション化します.
  • ContentFrame_Navigatingメソッドでは、このときのナビゲーションページの画像を記録します.
  •       void ContentFrame_Navigating(object sender, NavigatingCancelEventArgs e)
            {
                LastFrameContent = new WriteableBitmap(ContentFrame, null);
            }

    ContentFrame_Navigated(object sender,NavigationEventArgs)のメソッドでテンプレートページに値を割り当てます(この場合テンプレートページと呼びます)
      private void ContentFrame_Navigated(object sender, NavigationEventArgs e)
            {
                FrameMaskImage.Source = LastFrameContent;
                FrameStory.Begin();
            }

    3.第2のステップの画像を表示から非表示にするアニメーションを作成します.
    4.Frameコントロールに対して無から有へのアニメーション効果を行い、合わせるとページをめくる効果になります.
    具体的なXMALファイルコード:
        <Grid Name="FrameParentPanel" Margin="26,0,26,0" Grid.Row="2">
                    <Grid.Projection>
                        <PlaneProjection ></PlaneProjection>
                    </Grid.Projection>
                    <navigation:Frame x:Name="ContentFrame" Style="{StaticResource ContentFrameStyle}" 
                                  Source="/Home" Navigated="ContentFrame_Navigated" NavigationFailed="ContentFrame_NavigationFailed">
                    <navigation:Frame.UriMapper>
                      <uriMapper:UriMapper>
                        <uriMapper:UriMapping Uri="" MappedUri="/Views/Home.xaml"/>
                        <uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/>
                      </uriMapper:UriMapper>
                    </navigation:Frame.UriMapper>
                </navigation:Frame>
    
                    <!-- -->
                    <Image Name="FrameMaskImage" VerticalAlignment="Top"></Image>
                </Grid>
    具提.csコード:
     public partial class MainPage : UserControl
        {
            private Storyboard FrameStory { get; set; }
            private WriteableBitmap LastFrameContent { get; set; }
            private const int RotateLag = 300;
            private const int RotateTimeStep = 50;
            private const int RotateAngleStep = 15;
    
            public MainPage()
            {
                InitializeComponent();
                this.ContentFrame.Navigating += new NavigatingCancelEventHandler(ContentFrame_Navigating);
                InitFrameStory();
            }
    
            void ContentFrame_Navigating(object sender, NavigatingCancelEventArgs e)
            {
                LastFrameContent = new WriteableBitmap(ContentFrame, null);
            }
    
            void InitFrameStory()
            {
                // 
                var pageRotateAnimation = new DoubleAnimationUsingKeyFrames();
    
                for (var i = 0; i <= 12; i++)
                {
                    pageRotateAnimation.KeyFrames.Add(new DiscreteDoubleKeyFrame() { Value = RotateAngleStep * (i < 6 ? i : (i - 12)), KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(RotateLag + RotateTimeStep * i)) });
                }
    
                // 
                var maskAnimation = new ObjectAnimationUsingKeyFrames();
                maskAnimation.KeyFrames.Add(new DiscreteObjectKeyFrame() { Value = Visibility.Visible, KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(0)) });
                maskAnimation.KeyFrames.Add(new DiscreteObjectKeyFrame() { Value = Visibility.Collapsed, KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(RotateLag + RotateTimeStep * 6)) });
    
                //frame 
                var frameAnimation = new DoubleAnimationUsingKeyFrames();
                frameAnimation.KeyFrames.Add(new DiscreteDoubleKeyFrame() { Value = 0.0, KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(0)) });
                frameAnimation.KeyFrames.Add(new DiscreteDoubleKeyFrame() { Value = 1.0, KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(RotateLag + RotateTimeStep * 6)) });
    
                FrameStory = new Storyboard();
                FrameStory.Children.Add(pageRotateAnimation);
                FrameStory.Children.Add(maskAnimation);
                FrameStory.Children.Add(frameAnimation);
    
                Storyboard.SetTarget(pageRotateAnimation, FrameParentPanel.Projection);
                Storyboard.SetTarget(maskAnimation, FrameMaskImage);
                Storyboard.SetTarget(frameAnimation, ContentFrame);
                Storyboard.SetTargetProperty(pageRotateAnimation, new PropertyPath(PlaneProjection.RotationYProperty));
                Storyboard.SetTargetProperty(maskAnimation, new PropertyPath(VisibilityProperty));
                Storyboard.SetTargetProperty(frameAnimation, new PropertyPath(OpacityProperty));
            }
    
            // After the Frame navigates, ensure the HyperlinkButton representing the current page is selected
            private void ContentFrame_Navigated(object sender, NavigationEventArgs e)
            {
                FrameMaskImage.Source = LastFrameContent;
                FrameStory.Begin();
    
                foreach (UIElement child in LinksStackPanel.Children)
                {
                    HyperlinkButton hb = child as HyperlinkButton;
                    if (hb != null && hb.NavigateUri != null)
                    {
                        if (hb.NavigateUri.ToString().Equals(e.Uri.ToString()))
                        {
                            VisualStateManager.GoToState(hb, "ActiveLink", true);
                        }
                        else
                        {
                            VisualStateManager.GoToState(hb, "InactiveLink", true);
                        }
                    }
                }
            }
            // If an error occurs during navigation, show an error window
            private void ContentFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
            {
                e.Handled = true;
                ChildWindow errorWin = new ErrorWindow(e.Uri);
                errorWin.Show();
            }
        }