2016-09-16 101 views
0

我使用以下GridView並在其中包含3個元素的ItemTemplate爲VisualState動畫訪問ContentPresenter兒童

現在我想要做的是從GridViewItem的PointerOver動畫MyTextBlock不透明度。

<GridView x:Name="MyList" ItemContainerStyle="{StaticResource GridViewItemContainerStyle}" ItemsSource="{Binding MyList}"> 
<GridView.ItemTemplate> 
    <DataTemplate> 
     <Grid> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="200" /> 
       <RowDefinition Height="3" /> 
       <RowDefinition Height="80" /> 
      </Grid.RowDefinitions> 
      <Image Grid.Row="0" Source="{Binding Url}" /> 
      <ProgressBar Grid.Row="1" IsIndeterminate="True" /> 
      <TextBlock Name="MyTextBlock" Opacity="0" Text="Test" /> 
     </Grid> 
    </DataTemplate> 
</GridView.ItemTemplate> 
</GridView> 

ItemContainerStyle是這樣的。問題是,我無法訪問MyTextBlockStoryboard.TargetName="MyTextBlock",因爲它位於ContentPresenter之內。 我如何在ContentPresenter內做一個元素的視覺狀態動畫?

<Style TargetType="GridViewItem" x:Key="GridViewItemContainerStyle"> 
     ... 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="GridViewItem"> 
        <Grid x:Name="ContentBorder" Control.IsTemplateFocusTarget="True" RenderTransformOrigin="0.5,0.5">       
         <VisualStateManager.VisualStateGroups> 
          <VisualStateGroup x:Name="CommonStates"> 
           <VisualState x:Name="Normal"> 
            <Storyboard> 
             <PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter" /> 
            </Storyboard> 
           </VisualState> 
           <VisualState x:Name="PointerOver"> 
            <Storyboard> 
             <DoubleAnimation Storyboard.TargetName="BorderRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To="1" /> 
            </Storyboard> 
           </VisualState> 
          </VisualStateGroup> 
         </VisualStateManager.VisualStateGroups> 
         <Rectangle x:Name="BorderRectangle" Fill="{ThemeResource SystemControlHighlightListAccentLowBrush}" Opacity="0" /> 
         <ContentPresenter x:Name="ContentPresenter" ContentTransitions="{TemplateBinding ContentTransitions}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="{TemplateBinding Padding}" /> 
        </Grid> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

編輯: 我試着用以下TargetProperty,但它只是設置整個ContentPresenter 並不僅僅是TextBlock的不透明性在它的內部。

<DoubleAnimation Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="(TextBlock.Opacity)" Duration="0" To="1" /> 
+0

您是否嘗試在DataTemplate的網格控制內設置您的故事板? – AVK

+0

當我將Storyboard放入Grid.Resource中時,我無法從代碼隱藏中訪問它以啓動它。當我把它放入Page.Resource時,我得到一個「沒有檢測到安裝的組件」COMException。我想是因爲它不知道要開始哪一個。 –

回答

0

問題是,與Storyboard.TargetName = 「MyTextBlock」 從這裏我無法訪問MyTextBlock因爲它是ContentPresenter內。我如何做一個ContentPresenter中的元素的視覺狀態動畫?

您可以添加兩個visualstates裏面的DataTemplate(PointerEnteredPointerExited):

<GridView x:Name="MyList" Grid.Row="1" ItemContainerStyle="{StaticResource GridViewItemContainerStyle}" > 
     <GridView.ItemTemplate> 
      <DataTemplate> 
       <Grid PointerExited="Grid_PointerExited" PointerEntered="Grid_PointerEntered"> 
        <VisualStateManager.VisualStateGroups> 
         <VisualStateGroup> 
          <VisualState x:Name="PointerEntered"> 
           <Storyboard> 
            <DoubleAnimation Storyboard.TargetName="MyTextBlock" Storyboard.TargetProperty="Opacity" Duration="0" To="1" /> 
           </Storyboard> 
          </VisualState> 
          <VisualState x:Name="PointerExited"> 
           <Storyboard> 
            <DoubleAnimation Storyboard.TargetName="MyTextBlock" Storyboard.TargetProperty="Opacity" Duration="0" To="0" /> 
           </Storyboard> 
          </VisualState> 
         </VisualStateGroup> 
        </VisualStateManager.VisualStateGroups> 
        <Grid.RowDefinitions> 
         <RowDefinition Height="200" /> 
         <RowDefinition Height="3" /> 
         <RowDefinition Height="80" /> 
        </Grid.RowDefinitions> 
        <Image Grid.Row="0" Source="{Binding Url}" /> 
        <ProgressBar Grid.Row="1" IsIndeterminate="True" /> 
        <TextBlock Grid.Row="2" Name="MyTextBlock" Opacity="0" Text="Test" /> 
       </Grid> 
      </DataTemplate> 
     </GridView.ItemTemplate> 
</GridView> 

並使用Grid.PointerEnteredGrid.PointerExited事件以下代碼來獲取storyboard開始:

private void Grid_PointerExited(object sender, PointerRoutedEventArgs e) 
{ 
    Grid grid = sender as Grid; 
    var visualStateGroups = VisualStateManager.GetVisualStateGroups(grid); 
    var visualStateGroup = visualStateGroups[0]; 
    visualStateGroup.States[1].Storyboard.Begin(); 
} 

private void Grid_PointerEntered(object sender, PointerRoutedEventArgs e) 
{ 
    Grid grid = sender as Grid; 
    var visualStateGroups = VisualStateManager.GetVisualStateGroups(grid); 
    var visualStateGroup = visualStateGroups[0]; 
    visualStateGroup.States[0].Storyboard.Begin(); 
} 
+0

我接受了這個解決方案,因爲它解決了我的問題。但是如果contentPresenter沒有使用gridViewItem的全部大小,那麼你會怎麼做,因爲假設它周圍有一個邊距? –

0

DataTemplate可以來自任何地方(應用程序資源,窗口資源,本地資源,Cod e),所以它使用它自己的NameScope

由於Namescope問題,您無法使用MyTextBlock。因此,最好將VisualStates定義爲DataTemplate本身的一部分。