转到 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 代码中的一些问题。

  1. 需要删除以下行。这就像说 'go find a state named OverlayState on the checkedBorder element'。显然,该状态不在该元素上。此外,将 ElementName 绑定更改为指向顶层 Grid(视觉状态组所在的位置)也不起作用,稍后我将解释原因。

TargetObject="{Binding ElementName=checkedBorder}"

  1. 你应该总是给你的VisualStateGroup一个名字,像这样-

<VisualStateGroup x:Name="MyStates">

  1. 您需要在叠加层 Border 上将 IsHitTestVisible 设置为 False,否则带有图像背景的 Border 将无法接收 Tapped 事件,因为它位于覆盖事件的后面。

我觉得应该可以走了。但是,如果您现在 运行 该应用程序,您将收到一个未处理的异常

Target does not define any VisualStateGroups.

如果您重新添加 TargetObject ElementName 绑定并将其更改为指向顶层 Grid,异常将消失但不会调用视觉状态。

TargetObject="{Binding ElementName=myFirstLevelGridWhereTheVSGroupIs}"

这是因为正常的 VisualStateManager 只适用于 Controls 而不是 FrameworkElements 因为你的 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>

您现在应该可以看到动画效果了。 :)