2016-11-20 75 views
4

我目前正在爲我的應用程序開發一個自定義控件,該應用程序使用可以單擊以更改狀態的標題來擴展和收縮內容。目前它的模板看起來像這樣。如何使用視覺狀態動畫控制UWP中控件的可見性?

<Style TargetType="controls:ExpandControl"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="controls:ExpandControl"> 
       <Border> 
        <VisualStateManager.VisualStateGroups> 
         <VisualStateGroup x:Name="State"> 
          <VisualState x:Name="Visible"> 
           <VisualState.Setters> 
            <Setter Target="Grid.Visibility" Value="Visible" /> 
           </VisualState.Setters> 
          </VisualState> 

          <VisualState x:Name="Collapsed"> 
           <VisualState.Setters> 
            <Setter Target="Grid.Visibility" Value="Collapsed" /> 
           </VisualState.Setters> 
          </VisualState> 
         </VisualStateGroup> 
        </VisualStateManager.VisualStateGroups> 

        <Grid> 
         <Grid.RowDefinitions> 
          <RowDefinition Height="Auto" /> 
          <RowDefinition Height="*" /> 
         </Grid.RowDefinitions> 

         <ContentPresenter x:Name="HeaderPresenter" Content="{TemplateBinding Header}" /> 

         <Grid x:Name="Grid" Grid.Row="1"> 
          <ContentPresenter x:Name="ContentPresenter" Content="{TemplateBinding Content}" /> 
         </Grid> 
        </Grid> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

你可以從模板看,我目前使用的視覺狀態來設置此控件中的內容的知名度,但作爲內容就會消失它不是一個很好的用戶體驗。

我希望能夠以某種方式處理內容,以便在控件的可見性更改時,內容看起來像是從頭中摺疊並展開。

我已經看過使用故事板的動畫,但我對此完全陌生,如果任何人都可以在故事板上提供一些幫助,以及如何讓場景適用於我的控制,那將非常感謝!

在此先感謝!

回答

3

故事板在Visual Studio中不是一次輝煌的體驗,嘗試手動編寫它們可能不是最好的主意。

我建議在Blend中打開您的項目,它是Visual Studio安裝的一部分。它是設計應用程序的好工具,尤其是以非常簡單的方式添加Storyboard,並且在您看到設計器中的更改時,它會自動爲您生成Storyboard XAML。

至於你的動畫場景,我已經在你的XAML模板中玩過一個頁面,並且提出了一些使它看起來像崩潰和展開的東西,但它沒有像這樣操縱可見性屬性:

<VisualStateGroup x:Name="State"> 
    <VisualState x:Name="Visible"> 
     <Storyboard> 
      <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Grid"> 
       <EasingDoubleKeyFrame KeyTime="0" Value="0"/> 
       <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/> 
       <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="1"/> 
      </DoubleAnimationUsingKeyFrames> 
      <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="Grid"> 
       <EasingDoubleKeyFrame KeyTime="0" Value="0"/> 
       <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="1"/> 
      </DoubleAnimationUsingKeyFrames> 
      <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Grid"> 
       <DiscreteObjectKeyFrame KeyTime="0"> 
        <DiscreteObjectKeyFrame.Value> 
         <Visibility>Collapsed</Visibility> 
        </DiscreteObjectKeyFrame.Value> 
       </DiscreteObjectKeyFrame> 
       <DiscreteObjectKeyFrame KeyTime="0:0:0.1"> 
        <DiscreteObjectKeyFrame.Value> 
         <Visibility>Visible</Visibility> 
        </DiscreteObjectKeyFrame.Value> 
       </DiscreteObjectKeyFrame> 
      </ObjectAnimationUsingKeyFrames> 
     </Storyboard> 
    </VisualState> 

    <VisualState x:Name="Collapsed"> 
     <Storyboard> 
      <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Grid"> 
       <EasingDoubleKeyFrame KeyTime="0" Value="1"/> 
       <EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="0"/> 
      </DoubleAnimationUsingKeyFrames> 
      <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="Grid"> 
       <EasingDoubleKeyFrame KeyTime="0" Value="1"/> 
       <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0"/> 
      </DoubleAnimationUsingKeyFrames> 
      <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Grid"> 
       <DiscreteObjectKeyFrame KeyTime="0"> 
        <DiscreteObjectKeyFrame.Value> 
         <Visibility>Visible</Visibility> 
        </DiscreteObjectKeyFrame.Value> 
       </DiscreteObjectKeyFrame> 
       <DiscreteObjectKeyFrame KeyTime="0:0:0.2"> 
        <DiscreteObjectKeyFrame.Value> 
         <Visibility>Collapsed</Visibility> 
        </DiscreteObjectKeyFrame.Value> 
       </DiscreteObjectKeyFrame> 
      </ObjectAnimationUsingKeyFrames> 
     </Storyboard> 
    </VisualState> 
</VisualStateGroup> 

你還需要改變你的內容電網看起來像這樣:

<Grid x:Name="Grid" Grid.Row="1" RenderTransformOrigin="0.5,0"> 
    <Grid.RenderTransform> 
     <CompositeTransform/> 
    </Grid.RenderTransform> 

    <ContentPresenter x:Name="ContentPresenter" Content="{TemplateBinding Content}" /> 
</Grid> 

我會解釋爲什麼你就必須做出和改變電網的故事板下一步怎麼辦。

爲了實現類似於您所尋找的內容,我選擇了網格上的不透明度和Y比例來設置動畫效果。

因爲我們將操縱控件的Y尺度,所以我們將RenderTransform添加到了網格中。使用CompositeTransform的原因是,您可以操作最常見的變換(縮放,旋轉,平移等)。

在這些州,我們使用關鍵幀來操縱這些值。這是你如何實現故事板中的動畫。如果只設置一個KeyFrame的時間爲0,它將顯示爲類似於使用VisualState.Setters機制更改屬性的直接更改。

在Collapsed狀態下,我們將網格的不透明度和Y比例從1更改爲0.這給出了顯示內容摺疊到標題中的動畫。從關鍵幀中可以看到,我們錯開了兩個屬性的動畫,因此內容在完成操縱比例之前淡出。

在Visible狀態下,我們基本上是通過在相同的時間內將不透明度和Y縮放比例從0改爲1來顛倒Collapsed狀態。

嘗試將這些加載到您的控件中,並在Blend中與他們玩耍。這是一個很好的起點,因爲我很快就把它們放在一起。

您可以採用混合這裏故事板一些更多的信息:https://blogs.msdn.microsoft.com/avtarsohi/2016/02/16/understand-storyboard-concept-in-xaml-using-blend-2015/

+1

這會使用Visibility屬性變化仍然有效? – JCrook1121

+0

@ JCrook1121沒有理由不能使用它。我會更新我的答案以展示如何使用它。 –

+0

謝謝!我問的唯一原因是因爲如果您使用頁面頂部的某些內容的控件並在控件下面有更多內容,則您的示例運行不正常。當你摺疊它,它動畫看起來像它已經崩潰,但下面的內容不會碰到...... – JCrook1121

相關問題