在 Listivew 项目 DateTemplate windows phone 8.1 中转到 VisualState [英] Goto VisualState in Listivew item DateTemplate windows phone 8.1

查看:18
本文介绍了在 Listivew 项目 DateTemplate windows phone 8.1 中转到 VisualState的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的要求:当点击 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.

  1. 需要删除以下行.这就像说'去在 checkedBorder 元素上找到一个名为 OverlayState 的状态'.显然,该状态不在该元素上.此外,将 ElementName 绑定更改为指向顶级 Grid(视觉状态组所在的位置)也不起作用,我稍后会解释原因.
  1. The following line needs to be removed. It's like saying 'go find a state named OverlayState on the checkedBorder element'. Clearly that state is not on that element. Also, changing the ElementName binding to point to the top level Grid (where the visual state group is) won't work either, I will explain why later.

TargetObject="{Binding ElementName=checkedBorder}"

  1. 你应该总是给你的VisualStateGroup一个名称,就像这样 -
  1. You should always give your VisualStateGroup a name, like this -

  1. 您需要在叠加层 Border 上将 IsHitTestVisible 设置为 False,否则带有图像背景的 Border无法接收 Tapped 事件,因为它位于覆盖层后面.
  1. You need to set IsHitTestVisible to False on your overlay Border, otherwise the Border with image background will not be able to receive the Tapped 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.

Target does not define any VisualStateGroups.

如果您重新添加 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 Controls not FrameworkElements 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆