问题描述
我的要求:当点击 ListViewItem(DataTemplate) 中的边框时,叠加层应该出现在它上面并带有动画.
My requirement: when tapped on the border in ListViewItem(DataTemplate) an overlay should appear on top of it with animation.
在我的列表视图数据模板中,我在根定义了一个视觉状态.当用户点击边框时,我想进入视觉状态.我试过跟随 xaml 但它不起作用
In my listview data template I defined a visual state at the root. I want to goto the visual state when user taps on the border. I have tried following xaml but it is not working
<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>
推荐答案
这个问题比我最初想象的要复杂.
This question is more complex than I initially thought.
首先,让我们更正您的 xaml 代码中的一些问题.
First, let's correct a few issues in your xaml code.
- 需要删除以下行.这就像说'去在
checkedBorder
元素上找到一个名为OverlayState
的状态'.显然,该状态不在该元素上.此外,将ElementName
绑定更改为指向顶级Grid
(视觉状态组所在的位置)也不起作用,我稍后会解释原因.
- The following line needs to be removed. It's like saying 'go find a state named
OverlayState
on thecheckedBorder
element'. Clearly that state is not on that element. Also, changing theElementName
binding to point to the top levelGrid
(where the visual state group is) won't work either, I will explain why later.
TargetObject="{Binding ElementName=checkedBorder}"
- 你应该总是给你的
VisualStateGroup
一个名称,就像这样 -
- You should always give your
VisualStateGroup
a name, like this -
- 您需要在叠加层
Border
上将IsHitTestVisible
设置为False
,否则带有图像背景的Border
无法接收Tapped
事件,因为它位于覆盖层后面.
- You need to set
IsHitTestVisible
toFalse
on your overlayBorder
, otherwise theBorder
with image background will not be able to receive theTapped
event because it's sitting behind the overlay one.
我觉得去应该不错.但是,如果您现在运行该应用程序,您将收到一个未处理的异常说
I thought it should be good to go. However, if you run the app now, you will get an unhandled exception saying
Target 未定义任何 VisualStateGroup.
如果您重新添加 TargetObject
ElementName
绑定并将其更改为指向顶级 Grid
,异常将消失,但不调用视觉状态.
If you add back the TargetObject
ElementName
binding and change it to point to the top level Grid
, the exception will go away but the visual state is not called.
TargetObject="{Binding ElementName=myFirstLevelGridWhereTheVSGroupIs}"
这是因为普通的 VisualStateManager
仅适用于 Control
而不是 FrameworkElement
,因为您的 Grid
> 不是一种 Control
.
This is because a normal VisualStateManager
only works for Control
s not FrameworkElement
s since your Grid
is not a type of Control
.
在 WP Silverlight 应用程序中,修复起来相当简单.您需要做的就是添加一个内置的 CustomVisualStateManager
,它允许您在 VisualStateGroups
定义之上传递一个 FrameworkElement
.但是这样的类在 WinRT 中不存在.
In a WP Silverlight app, it's fairly simple to fix. All you need to do is to add a built-in CustomVisualStateManager
which allows you to pass in a FrameworkElement
on top of the VisualStateGroups
definition. But such class doesn't exist in WinRT.
我不久前问了一个关于这个的问题,最终想出了一个答案.
I asked a question about this a while ago and eventually came up with an answer.
将此类包含到您的项目中,并在您的 xaml 代码中添加引用,就在您的 VisualStateGroups
定义之前.
Include this class into your project, and add the reference in your xaml code, just before your VisualStateGroups
definition.
<VisualStateManager.CustomVisualStateManager>
<local:ExtendedVisualStateManager />
</VisualStateManager.CustomVisualStateManager>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="MyStates">
<VisualState x:Name="OverlayState">
最后,因为与 Silverlight 应用程序中的 GoToStateAction
不同,WinRT 的 GoToStateAction
不处理 CustomVisualStateManager
,您必须创建一个自定义GoToStateAction
也是.
Lastly, because unlike the GoToStateAction
in Silverlight app, the WinRT's GoToStateAction
doesn't handle CustomVisualStateManager
, you will have to create a custom GoToStateAction
too.
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>
您现在应该可以看到动画在工作.:)
You should be able to see the animation working now. :)
这篇关于在 Listivew 项目 DateTemplate windows phone 8.1 中转到 VisualState的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!