我的要求:当点击 ListViewItem(DataTemplate) 中的边框时,应在其顶部显示一个带有动画的覆盖层。
在我的 ListView 数据模板中,我在根定义了视觉状态。我想在用户点击边框时进入视觉状态。我尝试过遵循 xaml 但它不起作用
<DataTemplate x:Key="MyTemplate">
<Grid Background="{Binding ItemBackground}"
Margin="0,0,0,5" Height="auto">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup >
<VisualState x:Name="OverlayState">
<Storyboard >
<DoubleAnimation Storyboard.TargetName="checkedBorder"
Storyboard.TargetProperty="Opacity"
Duration="0"
To="1" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid Height="auto" Margin="14,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="110"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="55"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
</Grid.RowDefinitions>
<!--Image Section" -->
<Grid Height="108" Margin="0,8,0,0" VerticalAlignment="Top">
<Grid Margin="0">
<Border HorizontalAlignment="Left" Margin="0" VerticalAlignment="Bottom" Width="98" Height="98" CacheMode="BitmapCache" CornerRadius="30">
<Border.Background>
<ImageBrush ImageSource="{Binding ImageSource}" Stretch="Fill"></ImageBrush>
</Border.Background>
<i:Interaction.Behaviors>
<icore:EventTriggerBehavior EventName="Tapped">
<icore:GoToStateAction StateName="OverlayState" TargetObject="{Binding ElementName=checkedBorder}"></icore:GoToStateAction>
</icore:EventTriggerBehavior>
</i:Interaction.Behaviors>
</Border>
<!-- Overlay Border -->
<Border HorizontalAlignment="Left" Opacity="0" x:Name="checkedBorder" Margin="0" Background="#99000000" VerticalAlignment="Bottom"
Width="98" Height="98" CacheMode="BitmapCache" CornerRadius="30">
</Border>
</Grid>
</Grid>
</Grid>
</Grid>
</DataTemplate>
最佳答案
这个问题比我最初想象的要复杂。
首先,让我们更正 xaml 代码中的一些问题。
- 需要删除以下行。这就像说“去找一个名为
OverlayState
的州”关于checkedBorder
元素'。显然该状态不在该元素上。另外,更改ElementName
绑定(bind)指向顶层Grid
(视觉状态组所在的位置)也不起作用,稍后我会解释原因。
TargetObject="{Binding ElementName=checkedBorder}"
- 您应该始终提供您的
VisualStateGroup
一个名字,像这样 -
<VisualStateGroup x:Name="MyStates">
- 您需要设置
IsHitTestVisible
至False
在您的叠加层上Border
,否则Border
带有图像背景的将无法接收Tapped
事件,因为它位于覆盖事件后面。
我想应该可以走了。但是,如果您现在运行该应用程序,您将收到一个未处理的异常:
Target does not define any VisualStateGroups.
如果您加回TargetObject
ElementName
绑定(bind)并将其更改为指向顶层 Grid
,异常将会消失,但视觉状态不会被调用。
TargetObject="{Binding ElementName=myFirstLevelGridWhereTheVSGroupIs}"
这是因为正常的VisualStateManager
仅适用于 Control
不是FrameworkElement
自从您的 Grid
不是 Control
的类型.
在 WP Silverlight 应用程序中,修复起来相当简单。您需要做的就是添加内置 CustomVisualStateManager
它允许您传入 FrameworkElement
在 VisualStateGroups
之上定义。但 WinRT 中不存在这样的类。
我不久前问了一个关于这个问题的问题,最终得到了一个answer .
将此类包含到您的项目中,并在您的 xaml 代码中添加引用,就在您的 VisualStateGroups
之前定义。
<VisualStateManager.CustomVisualStateManager>
<local:ExtendedVisualStateManager />
</VisualStateManager.CustomVisualStateManager>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="MyStates">
<VisualState x:Name="OverlayState">
最后,因为与 GoToStateAction
不同在 Silverlight 应用程序中,WinRT 的 GoToStateAction
不处理CustomVisualStateManager
,您将必须创建一个自定义 GoToStateAction
也是。
public class ExtendedGoToStateAction : DependencyObject, IAction
{
public string StateName
{
get { return (string)GetValue(StateNameProperty); }
set { SetValue(StateNameProperty, value); }
}
public static readonly DependencyProperty StateNameProperty =
DependencyProperty.Register("StateName", typeof(string), typeof(ExtendedGoToStateAction), new PropertyMetadata(string.Empty));
public bool UseTransitions
{
get { return (bool)GetValue(UseTransitionsProperty); }
set { SetValue(UseTransitionsProperty, value); }
}
public static readonly DependencyProperty UseTransitionsProperty =
DependencyProperty.Register("UseTransitions", typeof(bool), typeof(ExtendedGoToStateAction), new PropertyMetadata(false));
public object Execute(object sender, object parameter)
{
return ExtendedVisualStateManager.GoToElementState((FrameworkElement)sender, this.StateName, this.UseTransitions);
}
}
并用这个替换内置的。
<i:Interaction.Behaviors>
<iCore:EventTriggerBehavior EventName="Tapped">
<local:ExtendedGoToStateAction StateName="OverlayState"/>
</Core:EventTriggerBehavior>
您现在应该能够看到动画正在运行。 :)
关于xaml - 转到 Listivew 项目 DateTemplate Windows Phone 8.1 中的 VisualState,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27899755/