65.9K
CodeProject 正在变化。 阅读更多。
Home

Silverlight 教程:使用 Storyboards 创建动画导航栏

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.07/5 (8投票s)

2008年7月22日

CPOL

6分钟阅读

viewsIcon

71749

downloadIcon

788

系列文章的第一篇。本文重点介绍如何使用 Storyboards 来创建动画效果。

点击此链接查看此项目的最终运行效果演示。

引言

本文是一个教程,介绍如何使用 Silverlight 2.0 创建一个类似于 Silverlight.net 网站顶部(以及我自己的网站 SilverlightWebApps.com 顶部)的精美动画导航栏。当鼠标悬停在您想要导航到的标题上时,背景会亮起并发出辉光,同时三角形指针会缩放到您指向的项。当您单击导航项时,Silverlight 页面上的内容面板将被替换为新选定的内容。

本文是系列文章的第一篇。在本篇文章中,我将重点介绍如何手动将 Storyboards 连接到鼠标事件,在第二篇文章中,我将展示如何使用 Visual State Manager 来实现这一点。

分步教程

简要说明

  1. 在 VS2008 中创建一个名为 TutorialNavbar 的空网站
  2. 添加新项,选择 Silverlight 应用程序,并将项目保存为 TutorialNavbarXap.csproj
  3. 选择“创建新的 Silverlight 项目”选项并将其添加到解决方案中

    image002.jpg

  4. 删除 VS2008 自动生成的 TutorialNavbarTestPage.aspx 文件。保留 TutorialNavbarTestPage.html 页面。我之所以喜欢从 Visual Studio 网站项目开始,而不是从 Expression Blend 项目开始,原因如下:
    • 在我看来,在 Expression Blend 中打开 C# 文件时,Intellisense 不起作用(至少在 Expression Blend 2.5 June Preview 版本中是这样——希望在正式发布版中会得到解决)。
    • 我认为您无法调试纯 Expression Blend 项目,而如果您像我上面描述的那样从 VS2008 项目开始,则断点可以正常工作。
    • Expression Blend 会创建自己的默认测试页面,您对此页面无法进行控制。这可能是一个问题,例如,如果您有一个页面比浏览器窗口大,默认的 Expression Blend 页面将没有滚动条。通过像我上面描述的那样创建项目,您可以根据需要修改样式表来添加这些元素。

    理论上,VS2008 和 Expression Blend 会协同工作并保持同步,这样您就可以在 VS2008 和/或 Expression Blend 环境中无缝地编辑文件,而不会遇到任何问题。但实际上,我曾遇到过这两个环境不同步的情况,您会发现从 Expression Blend 中按 F5 运行的项目在 VS2008 中却无法运行。要恢复同步,请确保 Expression Blend 中所有文件都已保存,按 F5 进行构建,然后从 VS2008 中尝试“构建”->“清理解决方案”,再“构建”->“重新生成全部”。

  5. 在 Expression Blend 2.5 June Preview 中打开新创建的项目 TutorialNavbarXap
  6. 创建一个在视觉上看起来与下图相似的内容。注意,为了获得绿色的背景高亮效果,我选择了一个径向渐变画笔,并将右侧停止点的透明度设置为 30%。将三角形指针命名为 NavIndicator,并将每个绿色高亮命名为 Nav1HighlightNav2HighlightNav3Highlight

    image003.jpg

  7. 在主页面上添加一个占据大部分页面的 Canvas,并将其命名为 ContentCanvas
  8. 创建一个矩形,该矩形覆盖了 Nav1Highlight 的整个绿色高亮区域以及箭头所在区域的下方。将此区域命名为 Nav1ClickArea。复制此矩形以创建 Nav1Nav2,并相应地命名。将每个区域的不透明度设置为 0%。顾名思义,这是您将要单击以进行导航的区域。
  9. 创建一些占位符页面以供导航。在 Expression Blend 中,转到项目视图,单击项目,然后选择“添加新项”。将项命名为 Nav1Page.xaml,并勾选“包含代码文件”复选框。对 Nav2Page.xamlNav3Page.xaml 重复此操作。在 Nav1Page.xaml 中,添加一个文本块,内容为“Nav1Page 占位符”。对 Nav2PageNav3Page 重复此操作,并相应更改文本内容。

    image004.jpg

  10. 选择 Nav1ClickArea,转到属性,选择事件按钮(闪电图标),然后在 MouseLeftButtonDown 事件下输入方法名 OnNav1Click

    image005.jpg

  11. 按 Enter 键后,VS2008 应该会启动,您会发现 Expression Blend 已在 page.xaml.cs 文件中输入了以下空方法。对 Nav2ClickAreaNav3ClickArea 重复上述步骤。
    private void OnNav1Click(object sender, MouseButtonEventArgs e) 
    { 
    
    } 
    • 我们正在创建将要显示的每个页面的实例。
    • 我们将 PageLoaded 方法附加到 Loaded 事件,并使用该方法将 Nav1Page 设置为默认页面。
    • 我们添加了代码到 OnNavClick 方法中,用于移除先前显示的页面并添加新页面。
    public partial class Page : UserControl
    { 
    Nav1Page m_nav1Page = new Nav1Page(); 
    Nav2Page m_nav2Page = new Nav2Page(); 
    Nav3Page m_nav3Page = new Nav3Page(); 
    
    public Page() 
    { 
    InitializeComponent(); 
    Loaded += new RoutedEventHandler(PageLoaded); 
    } 
    
    void PageLoaded(object sender, RoutedEventArgs e) 
    { 
    RemoveAll(); 
    ContentCanvas.Children.Add(m_nav1Page); 
    } 
    
    void RemoveAll() 
    { 
    ContentCanvas.Children.Remove(m_nav1Page); 
    ContentCanvas.Children.Remove(m_nav2Page); 
    ContentCanvas.Children.Remove(m_nav3Page); 
    } 
    
    private void OnNav1Click(object sender, MouseButtonEventArgs e) 
    { 
    RemoveAll(); 
    ContentCanvas.Children.Add(m_nav1Page); 
    } 
    
    private void OnNav2Click(object sender, MouseButtonEventArgs e) 
    { 
    RemoveAll(); 
    ContentCanvas.Children.Add(m_nav2Page); 
    } 
    
    private void OnNav3Click(object sender, MouseButtonEventArgs e) 
    { 
    RemoveAll(); 
    ContentCanvas.Children.Add(m_nav3Page); 
    } 
    }
  12. 构建并调试。您应该会看到,当您单击每个区域时,指定的页面就会出现。
  13. 现在让我们让高亮显示出现。如上所示,使用 MouseLeftButtonDown 事件,将 OnNav1Enter 方法名添加到 MouseEnter 事件。对 Nav2Nav3 重复此操作。
  14. 创建一个 HighlightNone 方法来使所有高亮显示不可见,然后从 PageLoaded 方法中调用它。然后在 OnNavEnter 方法中,调用 HighlightNone,然后调用使选定项高亮显示的方法。以下代码片段对此进行了说明:
    void PageLoaded(object sender, RoutedEventArgs e) 
    { 
    // Remove all content add then add the Nav1Page 
    RemoveAll(); 
    ContentCanvas.Children.Add(m_nav1Page); 
    
    // Highlight Nav1 
    HighlightNone(); 
    Nav1Highlight.Opacity = 100.0; 
    } 
    
    private void HighlightNone() 
    { 
    Nav1Highlight.Opacity = 0.0; 
    Nav2Highlight.Opacity = 0.0; 
    Nav3Highlight.Opacity = 0.0; 
    } 
    
    private void OnNav1Enter(object sender, MouseEventArgs e) 
    { 
    HighlightNone(); 
    Nav1Highlight.Opacity = 100.0; 
    } 
    
    private void OnNav2Enter(object sender, MouseEventArgs e) 
    { 
    HighlightNone(); 
    Nav2Highlight.Opacity = 100.0; 
    } 
    
    private void OnNav3Enter(object sender, MouseEventArgs e) 
    { 
    HighlightNone(); 
    Nav3Highlight.Opacity = 100.0; 
    }
  15. 构建并调试。您应该会看到,每当您鼠标悬停在不同的导航区域上时,高亮显示就会出现。

    image006.jpg

  16. 现在我们来为 NavIndicator 三角形添加动画。创建一个名为 MoveToNav2 的 storyboard。

    image007.jpg

  17. 不设置零时刻的关键帧,将时间轴移动到 1 秒,然后将 NavIndicator 三角形拖动到 Nav2 下方的居中位置。

    image008.jpg

  18. 单击 NavIndicator 的关键帧标记,并将缓动效果调整为 x1=0 和 x2=.5。如果您在单击 NavIndicator 关键帧时未看到下方的缓动框,请确保属性框设置为“属性”而不是“事件”。播放 storyboard 以查看这些调整的效果。完成后关闭 storyboard。

    image009.jpg

  19. 现在转到 XAML 视图,查看为该 storyboard 生成的代码。您将看到两个以 DoubleAnimationUsingKeyFrames 开头的节。第一个动画化 X 方向,如以下行所示:Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)
    第二个 DoubleAnimationUsingKeyFrames 动画化 Y 方向,如 TranslateTransform.Y 项所示。我们只想让 NavIndicator 水平移动,因此删除第二个 DoubleAnimationUsingKeyFrames 部分。

    image010.jpg

  20. 现在复制整个 storyboard,但更改两处内容:
    • 将 storyboard 的名称更改为 MoveToNav1,如下所示:
      <Storyboard x:Name="MoveToNav1"> 
    • SplineDoubleKeyFrame Value 更改为 0,如下所示:
      <SplineDoubleKeyFrame KeyTime="00:00:01" Value="0"> 

    这样做是创建了一个相同的 storyboard,但它不是移动到 Nav2 位置,而是移动回原来的位置(即 0)。我们将对 MoveToNav3 执行相同的操作。Nav3 的值是如何移动的?我实际上创建了一个使用“对象和时间线”菜单的 MoveToNav3 storyboard,读取了 X 移动的值,然后将该值复制到我基于上述 MoveToNav2 storyboard 创建的自己的 XAML storyboard 中。如果您不想处理 XAML,您可以为上面的原始 MoveToNav2 storyboard 重复上述步骤,为每个其他移动操作执行相同的操作。

  21. 现在添加代码,以便在鼠标经过导航区域时启动相应的动画。
    private void OnNav1Enter(object sender, MouseEventArgs e) 
    { 
    HighlightNone(); 
    Nav1Highlight.Opacity = 100.0; 
    MoveToNav1.Begin(); 
    } 
    
    private void OnNav2Enter(object sender, MouseEventArgs e) 
    { 
    HighlightNone(); 
    Nav2Highlight.Opacity = 100.0; 
    MoveToNav2.Begin(); 
    } 
    
    private void OnNav3Enter(object sender, MouseEventArgs e) 
    { 
    HighlightNone(); 
    Nav3Highlight.Opacity = 100.0; 
    MoveToNav3.Begin(); 
    }
  22. 嗯……一秒钟对于这个过渡来说有点慢。让我们将过渡时间改为 0.5 秒。转到 XAML,将时间从 1 秒更改为半秒。
    <Storyboard x:Name="MoveToNav1">
        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"… 
            <SplineDoubleKeyFrame KeyTime="00:00:00.50" Value="0">
  23. 好多了!就是这样。现在您已经有了一个动画导航栏。

历史

© . All rights reserved.