转到 Listivew 项 DateTemplate 中的 VisualState windows phone 8.1
Goto VisualState in Listivew item DateTemplate windows phone 8.1
我的要求:当点击 ListViewItem(DataTemplate) 的边框时,叠加层应出现在其顶部并带有动画。
在我的列表视图数据模板中,我在根目录定义了一个视觉状态。当用户点击边框时,我想转到视觉状态。我已尝试关注 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 代码中的一些问题。
- 需要删除以下行。这就像说 'go find a state named
OverlayState
on the checkedBorder
element'。显然,该状态不在该元素上。此外,将 ElementName
绑定更改为指向顶层 Grid
(视觉状态组所在的位置)也不起作用,稍后我将解释原因。
TargetObject="{Binding ElementName=checkedBorder}"
- 你应该总是给你的
VisualStateGroup
一个名字,像这样-
<VisualStateGroup x:Name="MyStates">
- 您需要在叠加层
Border
上将 IsHitTestVisible
设置为 False
,否则带有图像背景的 Border
将无法接收 Tapped
事件,因为它位于覆盖事件的后面。
我觉得应该可以走了。但是,如果您现在 运行 该应用程序,您将收到一个未处理的异常
Target does not define any VisualStateGroups.
如果您重新添加 TargetObject
ElementName
绑定并将其更改为指向顶层 Grid
,异常将消失但不会调用视觉状态。
TargetObject="{Binding ElementName=myFirstLevelGridWhereTheVSGroupIs}"
这是因为正常的 VisualStateManager
只适用于 Control
s 而不是 FrameworkElement
s 因为你的 Grid
不是 Control
.
在 WP Silverlight 应用程序中,修复起来相当简单。您需要做的就是添加一个内置的 CustomVisualStateManager
,它允许您在 VisualStateGroups
定义之上传递一个 FrameworkElement
。但是这样的 class 在 WinRT 中不存在。
我刚才问了一个关于这个的问题,最后想出了一个 answer。
将此 class 包含到您的项目中,并在您的 xaml 代码中添加引用,就在您的 VisualStateGroups
定义之前。
<VisualStateManager.CustomVisualStateManager>
<local:ExtendedVisualStateManager />
</VisualStateManager.CustomVisualStateManager>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="MyStates">
<VisualState x:Name="OverlayState">
最后,因为与 Silverlight 应用程序中的 GoToStateAction
不同,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>
您现在应该可以看到动画效果了。 :)
我的要求:当点击 ListViewItem(DataTemplate) 的边框时,叠加层应出现在其顶部并带有动画。
在我的列表视图数据模板中,我在根目录定义了一个视觉状态。当用户点击边框时,我想转到视觉状态。我已尝试关注 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 代码中的一些问题。
- 需要删除以下行。这就像说 'go find a state named
OverlayState
on thecheckedBorder
element'。显然,该状态不在该元素上。此外,将ElementName
绑定更改为指向顶层Grid
(视觉状态组所在的位置)也不起作用,稍后我将解释原因。
TargetObject="{Binding ElementName=checkedBorder}"
- 你应该总是给你的
VisualStateGroup
一个名字,像这样-
<VisualStateGroup x:Name="MyStates">
- 您需要在叠加层
Border
上将IsHitTestVisible
设置为False
,否则带有图像背景的Border
将无法接收Tapped
事件,因为它位于覆盖事件的后面。
我觉得应该可以走了。但是,如果您现在 运行 该应用程序,您将收到一个未处理的异常
Target does not define any VisualStateGroups.
如果您重新添加 TargetObject
ElementName
绑定并将其更改为指向顶层 Grid
,异常将消失但不会调用视觉状态。
TargetObject="{Binding ElementName=myFirstLevelGridWhereTheVSGroupIs}"
这是因为正常的 VisualStateManager
只适用于 Control
s 而不是 FrameworkElement
s 因为你的 Grid
不是 Control
.
在 WP Silverlight 应用程序中,修复起来相当简单。您需要做的就是添加一个内置的 CustomVisualStateManager
,它允许您在 VisualStateGroups
定义之上传递一个 FrameworkElement
。但是这样的 class 在 WinRT 中不存在。
我刚才问了一个关于这个的问题,最后想出了一个 answer。
将此 class 包含到您的项目中,并在您的 xaml 代码中添加引用,就在您的 VisualStateGroups
定义之前。
<VisualStateManager.CustomVisualStateManager>
<local:ExtendedVisualStateManager />
</VisualStateManager.CustomVisualStateManager>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="MyStates">
<VisualState x:Name="OverlayState">
最后,因为与 Silverlight 应用程序中的 GoToStateAction
不同,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>
您现在应该可以看到动画效果了。 :)