[UWP]DataTemplate 中包含的 Storyboard 无法正常工作

[UWP]The storyboard contained in the DataTemplate is not working properly

点击任何项目只会在第一个项目的情节提要上起作用。

您可以从以下地址下载源码。

http://util.aquerytool.com/Download?fileName=ItemStoryboardApp.zip

感谢您的回复。

<UserControl
    x:Class="ItemStoryboardApp.View.ItemListMVVMLightView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:ItemStoryboardApp.View"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:core="using:Microsoft.Xaml.Interactions.Core"
    xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
    xmlns:media="using:Microsoft.Xaml.Interactions.Media"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400">

    <Grid x:Name="PART_RootPanel">

        <ItemsControl ItemsSource="{Binding ItemList}" Padding="0,0,0,0">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Button Foreground="White" Margin="0,0,5,0" Padding="0,0,0,0" Height="40" Command="{Binding DataContext.SelectedItemCommand, ElementName=PART_RootPanel}" CommandParameter="{Binding}" VerticalContentAlignment="Stretch" >
                        <Button.Content>
                            <Grid x:Name="PART_ContinuousDefectPanel" RenderTransformOrigin="0.5, 0.5">
                                <Grid.Resources>
                                    <Storyboard x:Name="SB_ChangedCount">
                                        <DoubleAnimation Storyboard.TargetName="PART_ContinuousDefectPanel" Duration="0:0:0.25" To="1.2" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)" AutoReverse="True" />
                                        <DoubleAnimation Storyboard.TargetName="PART_ContinuousDefectPanel" Duration="0:0:0.25" To="1.2" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)" AutoReverse="True" />
                                    </Storyboard>
                                </Grid.Resources>

                                <Grid.RenderTransform>
                                    <ScaleTransform x:Name="ImageScale" ScaleX="1" ScaleY="1" />
                                </Grid.RenderTransform>

                                <interactivity:Interaction.Behaviors>
                                    <core:DataTriggerBehavior Binding="{Binding IsSelected}" Value="True"  ComparisonCondition="Equal">
                                        <media:ControlStoryboardAction Storyboard="{StaticResource SB_ChangedCount}" />
                                    </core:DataTriggerBehavior>
                                </interactivity:Interaction.Behaviors>

                                <Rectangle Fill="Orange" RadiusX="10" RadiusY="10"/>
                                <StackPanel Orientation="Horizontal" Margin="10,0,10,0" VerticalAlignment="Center">
                                    <TextBlock Text="{Binding ItemName}" />
                                </StackPanel>

                            </Grid>
                        </Button.Content>
                    </Button>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

    </Grid>

</UserControl>



public class ItemListMVVMLightViewModel : ViewModelBase
{
    public ObservableCollection<ItemModel> ItemList
    {
        get { return _itemList; }
        set { _itemList = value; RaisePropertyChanged("ItemList"); }
    }
    ObservableCollection<ItemModel> _itemList = new ObservableCollection<ItemModel>();

    public ICommand SelectedItemCommand { get; private set; }


    public ItemListMVVMLightViewModel()
    {
        InitData();
        InitCommand();
    }

    void InitCommand()
    {
        SelectedItemCommand = new RelayCommand<object>((param) => OnSelectedItemCommand(param));
    }

    void InitData()
    {
        for (int i = 0; i < 10; i++)
        {
            ItemList.Add(new ItemModel() { ItemName = "Name" + i.ToString() });
        }
    }

    void OnSelectedItemCommand(object param)
    {
        if (param == null || (param is ItemModel) == false)
        {
            return;
        }

        foreach (ItemModel i in ItemList)
        {
            i.IsSelected = false;
        }

        ItemModel item = param as ItemModel;
        item.IsSelected = true;
    }



}

根据Storyboard class,

TargetNameProperty is used to reference another element by its name.For most animation targeting scenarios you won't need to worry about the influence of XAML namescopes, but you might encounter XAML name resolution issues if you're trying to target template parts, or objects that were created using Load(String) and subsequently added to the object tree. For more info, see XAML namescopes.

由于您在数据模板中使用故事板,您可能会遇到 XAML 名称解析问题。故事板始终针对第一项可能会导致此问题。

在您的代码片段中,您使用 DataTrigger 来触发故事板。但是,它可能是 VisualStateManager 支持之前 WPF 和 Silverlight 早期版本的遗留语法。我推荐你storyboard animations for visual states。以下代码可能会达到您希望参考的相同结果。我想你想在选择一个项目后对其进行动画处理。我自定义按钮样式以将您的动画添加到 VisualStateManager.

<ItemsControl Padding="0,0,0,0" ItemsSource="{Binding ItemList}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Button
                    Height="40"
                    Margin="0,0,5,0"
                    Padding="0,0,0,0"
                    VerticalContentAlignment="Stretch"
                    Foreground="White"
                    Command="{Binding DataContext.SelectedItemCommand, ElementName=PART_RootPanel}"
                    CommandParameter="{Binding}">
                    <Button.Style>
                        <Style TargetType="Button">
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="Button">
                                        <Grid x:Name="RootGrid" Background="{TemplateBinding Background}">
                                            <Grid.RenderTransform>
                                                <ScaleTransform
                                                    x:Name="ImageScale"
                                                    ScaleX="1"
                                                    ScaleY="1" />
                                            </Grid.RenderTransform>
                                            <Rectangle
                                                Fill="Orange"
                                                RadiusX="10"
                                                RadiusY="10" />
                                            <StackPanel
                                                Margin="10,0,10,0"
                                                VerticalAlignment="Center"
                                                Orientation="Horizontal">
                                                <TextBlock Text="{Binding ItemName}" />
                                            </StackPanel>
                                            <VisualStateManager.VisualStateGroups>
                                                <VisualStateGroup x:Name="CommonStates">
                                                    <VisualState x:Name="Pressed">
                                                        <Storyboard>
                                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Background">
                                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundBaseMediumLowBrush}" />
                                                            </ObjectAnimationUsingKeyFrames>
                                                            <PointerDownThemeAnimation Storyboard.TargetName="RootGrid" />
                                                            <DoubleAnimation
                                                                AutoReverse="True"
                                                                Duration="0:0:0.25"
                                                                Storyboard.TargetName="RootGrid"
                                                                Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"
                                                                To="1.2" />
                                                            <DoubleAnimation
                                                                AutoReverse="True"
                                                                Duration="0:0:0.25"
                                                                Storyboard.TargetName="RootGrid"
                                                                Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
                                                                To="1.2" />
                                                        </Storyboard>
                                                    </VisualState>
                                                </VisualStateGroup>
                                            </VisualStateManager.VisualStateGroups>
                                        </Grid>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </Button.Style>
                </Button>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>