2011-03-02 49 views
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> 

起初,所有四個頁面網格被隱藏,並調整到零尺寸,但是當你點擊它的相應按鈕時,頁面應該有出現生長動畫。當你點擊另一個按鈕時,上一頁應該隨着縮小的動畫消失,而另一頁應該隨着動畫的增長而出現。通過這種方式,您可以使用按鈕在所有四頁之間切換。

從我讀過的內容來看,「正確」的做法是在用戶控件上使用視覺狀態。所以我創建了四個狀態,第1頁到第4頁,併爲每個狀態設置了適當的頁面網格來顯示。然後,我將命令放在按鈕上以更改用戶控件的視覺狀態。這工作得很好,我可以在頁面之間切換,但是當我開始嘗試在我遇到問題的狀態之間定義動畫時。

起初,我想我可以爲每個狀態定義一個'To *'和'From *'動畫。所以當你處於Page1狀態時,點擊按鈕進入狀態Page 2,它將播放隱藏Page1的'From *'動畫,然後顯示Page2的'To *'動畫。但這不起作用。即使您已經爲每個狀態定義了「To *」和「From *」動畫,Silverlight只會播放「To *」動畫,並完全忽略「From *」動畫!

更糟的是,這似乎是Silverlight應該如何工作的行爲,儘管它根本沒有意義!這意味着如果我想讓每個頁面縮小,然後再增加一個頁面,我必須定義從每個狀態到另一個狀態的單獨轉換!對於我目前的四頁,這將意味着十二個單獨的過渡,但是當我想增加頁數時,這個數字將會上升。十頁將需要9 * 9 = 81轉換!所有這些都使當前頁面縮小,新頁面增加。

我不能相信這有沒有更好的辦法來處理似乎是這樣一個簡單的情況,但沒有我能找到似乎說如何。我大概可以砍它一起使用代碼隱藏修飾故事板,但我想允許在Blend查看和編輯頁面網格,也一切我讀到說避免使用代碼隱藏和使用視圖模型和可視狀態來處理事情

請告訴我我錯過了明顯的東西?

回答

3

在Blend中,您只需在States選項卡中單擊狀態即可開始狀態記錄,定義狀態應該是什麼樣子,並設置狀態轉換持續時間。

你不應該擔心每個單獨的狀態轉換置換,除非你想讓每個狀態轉換不同。

如果您的狀態使用不能「線性」動畫的屬性(如更改可見性),請檢查FluidLayout按鈕。

編輯: 您可以使用每個狀態僅使用一個附加故事板 - 任意 - > {狀態}轉換來創建「完全收縮,然後增長」效果,將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> 

+0

是的,我試過了,但不幸的是,產生過渡的Silverlight開始在同一時間轉換的所有屬性。我需要將可見面板縮小爲無,通過將其X和Y變換縮放爲零,然後THEN使新面板以相反方式出現。啊哈! – 2011-03-03 15:56:27

+0

啊!這很有用,非常感謝!起初我有點麻煩,因爲我將每個網格的可見性設置爲摺疊狀態,並將其淡出,但生成的轉換立即應用更改,因此您不會看到它縮小。如果我將它放在可見的位置,但縮小並且不透明度爲零,則事情看起來是正確的。再次感謝! – 2011-03-03 20:33:40

相關問題