访问 Visualstate 动画的 ContentPresenter 子级
Access ContentPresenter children for Visualstate animation
我正在使用以下 GridView
并且有一个 ItemTemplate
里面有 3 个元素。
现在我想做的是在 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
是这样的。问题是,我无法从这里使用 Storyboard.TargetName="MyTextBlock"
访问 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" />
Problem is, i can't access MyTextBlock with Storyboard.TargetName="MyTextBlock" from here since it's inside the ContentPresenter. How can i do a visualstate animation of an element inside the ContentPresenter?
你可以在DataTemplate中添加两个visualstates
(PointerEntered
和PointerExited
):
<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.PointerEntered
和 Grid.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();
}
DataTemplate
可以来自任何地方(应用程序资源、Window 资源、本地资源、代码),因此它使用自己的 NameScope
。
由于 Namescope
个问题,您无法使用 MyTextBlock
。因此,最好将 VisualStates
定义为 DataTemplate
本身的一部分。
我正在使用以下 GridView
并且有一个 ItemTemplate
里面有 3 个元素。
现在我想做的是在 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
是这样的。问题是,我无法从这里使用 Storyboard.TargetName="MyTextBlock"
访问 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" />
Problem is, i can't access MyTextBlock with Storyboard.TargetName="MyTextBlock" from here since it's inside the ContentPresenter. How can i do a visualstate animation of an element inside the ContentPresenter?
你可以在DataTemplate中添加两个visualstates
(PointerEntered
和PointerExited
):
<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.PointerEntered
和 Grid.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();
}
DataTemplate
可以来自任何地方(应用程序资源、Window 资源、本地资源、代码),因此它使用自己的 NameScope
。
由于 Namescope
个问题,您无法使用 MyTextBlock
。因此,最好将 VisualStates
定义为 DataTemplate
本身的一部分。