0

我有一个似乎相当简单的场景,我试图在 Silverlight 中实现,但是尽管 Silverlight/Blend 4 中的所有令人难以置信的强大转换功能,我只是不知道如何去做。

我有一个布局可以归结为:

<UserControl>
    <Grid>
        <StackPanel>
            <Button x:Name="Button1" />
            <Button x:Name="Button2" />
            <Button x:Name="Button3" />
            <Button x:Name="Button4" />
        </StackPanel>
        <Grid x:Name="Page1" />
        <Grid x:Name="Page2" />
        <Grid x:Name="Page3" />
        <Grid x:Name="Page4" />
    </Grid>
</UserControl>

起初,所有四个页面网格都被隐藏并缩放到零大小,但是当您单击其相应的按钮时,页面应该会出现一个增长的动画。当您单击另一个按钮时,前一页应以缩小的动画消失,而另一页应以增长的动画出现。这样,您可以使用按钮在所有四个页面之间切换。

从我读过的内容来看,执行此操作的“正确”方法是在用户控件上使用视觉状态。所以我创建了四个状态,Page1 到 Page4,并为每个状态设置适当的页面网格来显示。然后我将命令放在按钮上以更改用户控件的视觉状态。这很好用,我可以在页面之间切换,但是当我开始尝试定义状态之间的动画时,我遇到了问题。

起初,我以为我可以为每个状态定义一个“To *”和“From *”动画。因此,当您处于 Page1 状态并单击按钮转到状态 Page2 时,它会播放“From *”动画隐藏 Page1,然后播放“To *”动画显示 Page2。但这不起作用。即使您为每个状态定义了“To *”和“From *”动画,Silverlight 也只会播放“To *”动画,而完全忽略“From *”动画!

更糟糕的是,这种行为似乎是 Silverlight 的工作方式,尽管它根本没有任何意义!这意味着如果我想让每个页面缩小,然后另一个页面在其位置增长,我将必须定义从每个状态到另一个状态的单独转换!对于我目前的四页,这意味着十二个单独的过渡,但是当我想增加页数时,这个数字会猛增。十页需要 9*9 = 81 次转换!一切都是为了缩小当前页面,并扩大新页面。

我不敢相信没有更好的方法来处理看似如此简单的场景,但我找不到任何东西似乎可以说明如何。我可能可以使用修改故事板的代码隐藏将它一起破解,但我希望允许在 Blend 中查看和编辑页面网格,而且我读到的所有内容都说要避免使用代码隐藏并使用视图模型和视觉状态来处理事情

请告诉我我遗漏了一些明显的东西?

4

1 回答 1

3

在 Blend 中,您只需单击“状态”选项卡中的状态即可开始状态记录,定义状态应该是什么样子,并设置状态转换持续时间。

您不必担心每个单独的状态转换排列,除非您希望每个状态都不同。

如果您的状态使用不能“线性”动画的属性(例如更改可见性),请检查 FluidLayout 按钮。

编辑:您可以创建您描述的“完全缩小然后增长”效果,每个状态只使用一个额外的故事板 - Any -> {State} 转换,在增长当前元素之前将 BeginTime 设置为延迟。

<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
mc:Ignorable="d"
x:Class="CommandingLeakWithScrollbar.UserControl1"
d:DesignWidth="640" d:DesignHeight="480">

<Grid x:Name="LayoutRoot">
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="VisualStateGroup">
            <VisualStateGroup.Transitions>
                <VisualTransition GeneratedDuration="0:0:1"/>
                <VisualTransition GeneratedDuration="0:0:1" To="Page1">
                    <Storyboard>
                        <DoubleAnimation BeginTime="0:0:1" Duration="0:0:1" To="640" Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="grid1" d:IsOptimized="True" />
                        <DoubleAnimation BeginTime="0:0:1" Duration="0:0:1" To="480" Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="grid1" d:IsOptimized="True"/>
                    </Storyboard>
                </VisualTransition>
                <VisualTransition GeneratedDuration="0:0:1" To="Page2">
                    <Storyboard>
                        <DoubleAnimation BeginTime="0:0:1" Duration="0:0:1" To="640" Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="grid2" d:IsOptimized="True" />
                        <DoubleAnimation BeginTime="0:0:1" Duration="0:0:1" To="480" Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="grid2" d:IsOptimized="True"/>
                    </Storyboard>
                </VisualTransition>
                <VisualTransition From="None" GeneratedDuration="0:0:1" To="Page1"/>
                <VisualTransition From="None" GeneratedDuration="0:0:1" To="Page2"/>
            </VisualStateGroup.Transitions>
            <VisualState x:Name="None"/>
            <VisualState x:Name="Page1">
                <Storyboard>
                    <DoubleAnimation Duration="0" To="640" Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="grid1" d:IsOptimized="True" />
                    <DoubleAnimation Duration="0" To="480" Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="grid1" d:IsOptimized="True" />
                </Storyboard>
            </VisualState>
            <VisualState x:Name="Page2">
                <Storyboard>
                    <DoubleAnimation Duration="0" To="640" Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="grid2" d:IsOptimized="True"/>
                    <DoubleAnimation Duration="0" To="480" Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="grid2" d:IsOptimized="True"/>
                </Storyboard>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    <Grid x:Name="grid1"  Background="Beige" Width="40" Height="40" HorizontalAlignment="Left" VerticalAlignment="Top"/>
    <Grid x:Name="grid2" HorizontalAlignment="Right" Width="40" Height="40" VerticalAlignment="Top" Background="Wheat" />
    <Grid HorizontalAlignment="Left" Width="40" Height="40" VerticalAlignment="Bottom" />
    <Grid HorizontalAlignment="Right" Width="40" Height="40" VerticalAlignment="Bottom"/>
    <StackPanel HorizontalAlignment="Center">
        <Button Content="Reset" >
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                    <ei:GoToStateAction StateName="None"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>
        <Button Content="Page1" >
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                    <ei:GoToStateAction StateName="Page1"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>
        <Button Content="Page2" >
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                    <ei:GoToStateAction StateName="Page2"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>
    </StackPanel>
</Grid>

于 2011-03-02T21:54:46.963 回答