Silverlight Storyboard of DataTemplate

本文关键字:DataTemplate of Storyboard Silverlight | 更新日期: 2023-09-27 18:13:36

我正在研究水平列表,当你将鼠标悬停在它上面时,每个项目都会展开。

我读了一些教程,我能够用MouseEnterMouseLeave事件创建简单的动画,但是,它在我的数据模板中不起作用。

尝试1

<DataTemplate x:Key="StepBreadcrumbItem">
            <Border BorderBrush="Gray" HorizontalAlignment="Stretch" Width="60">
                <Border.Triggers>
                    <EventTrigger RoutedEvent="Border.MouseEnter">
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation Duration="0:0:0.5" To="100" Storyboard.TargetProperty="(FrameworkElement.Width)" d:IsOptimized="True"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                    <EventTrigger RoutedEvent="Border.MouseLeave">
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation BeginTime="0:0:1" Duration="0:0:0.5" To="60" Storyboard.TargetProperty="(FrameworkElement.Width)" d:IsOptimized="True"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                </Border.Triggers>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text=" > " />
                    <TextBlock Text="{Binding Order, Mode=OneWay, StringFormat='{}. '}"/>
                    <TextBlock Text="{Binding Name, Mode=OneWay}"/>
                </StackPanel>
            </Border>
        </DataTemplate>

我错过了什么?对于单个元素可以正常工作。我得到运行时错误Error: Unhandled Error in Silverlight Application Code: 2531
Category: ParserError
Message: Failed to assign to property 'System.Windows.EventTrigger.RoutedEvent'.

2我现在使用MouseEnter事件以不同的方式实现了它。

<DataTemplate x:Key="StepBreadcrumbItem">
            <Border BorderBrush="Gray" HorizontalAlignment="Stretch" Width="60" MouseLeave="CollapseBreadcrumb" MouseEnter="ExpandBreadcrumb">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text=" > " />
                    <TextBlock Text="{Binding Order, Mode=OneWay, StringFormat='{}. '}"/>
                    <TextBlock Text="{Binding Name, Mode=OneWay}"/>
                </StackPanel>
            </Border>
        </DataTemplate>
private void CollapseBreadcrumb(object sender, System.Windows.Input.MouseEventArgs e)
        {
            var border = sender as Border;
            var duration = TimeSpan.FromMilliseconds(1000);
            var sb = new Storyboard { Duration = duration };
            var doubleAnimation = new DoubleAnimation
            {
                BeginTime = TimeSpan.FromSeconds(1),
                Duration = duration,
                To = 50
            };
            sb.Children.Add(doubleAnimation);
            Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(FrameworkElement.Width)"));
            Storyboard.SetTarget(doubleAnimation, border);
            sb.Begin();
        }
        private void ExpandBreadcrumb(object sender, System.Windows.Input.MouseEventArgs e)
        {
            var border = sender as Border;
            var duration = TimeSpan.FromMilliseconds(1000);
            var sb = new Storyboard {Duration = duration};
            var doubleAnimation = new DoubleAnimation
            {
                BeginTime = TimeSpan.FromSeconds(0),
                Duration = duration,
                To = 100
            };
            sb.Children.Add(doubleAnimation);
            Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(FrameworkElement.Width)"));
            Storyboard.SetTarget(doubleAnimation, border);
            sb.Begin();
        }

然而,现在它只在鼠标经过时展开,在鼠标离开时停止,并且不运行坍缩。我之所以用编程的方式设置storyboard是因为当我定义了两个storyboard然后重新分配并将其运行到不同的项目时当我在所有列表项目上移动鼠标时,它看起来非常糟糕

Silverlight Storyboard of DataTemplate

遗憾的是Silverlight只支持Loaded EventTrigger。

解决方法很容易,使用Behaviors。你只需要使用ControlStoryboardActionGoToStateAction来触发动画。

像这样,

    <i:Interaction.Triggers>
        <i:EventTrigger EventName="MouseEnter">
            <ei:ControlStoryboardAction Storyboard="{StaticResource Storyboard1}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>

这和这可能是一个好的开始。:)

你最好在你的xaml中做这种动画。基本上你需要创建一个可视状态组,它有两个状态:Normal和MouseOver。然后使用GoToStateAction触发它们。

You would have something like this,
            <Border x:Name="border" Width="60" Background="Gray">
                <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup x:Name="VisualStateGroup">
                        <VisualStateGroup.Transitions>
                            <VisualTransition/>
                        </VisualStateGroup.Transitions>
                        <VisualState x:Name="Normal"/>
                        <VisualState x:Name="MouseOver">
                            <Storyboard>
                                <!-- your storyboard here -->
                            </Storyboard>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateManager.VisualStateGroups>
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="MouseLeave">
                        <ei:GoToStateAction StateName="Normal"/>
                    </i:EventTrigger>
                    <i:EventTrigger EventName="MouseEnter">
                        <ei:GoToStateAction StateName="MouseOver"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>

更新2

实际上你甚至不需要创建可视状态组…像这样使用ControlStoryboardAction

    <DataTemplate x:Key="ItemTemplate">
        <Border x:Name="border" Width="60" Background="Gray" RenderTransformOrigin="0.5,0.5">
            <Border.Resources>
                <Storyboard x:Name="expand">
                    <DoubleAnimation Duration="0:0:0.4" To="100" Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="border" d:IsOptimized="True"/>
                </Storyboard>
                <Storyboard x:Name="collapse">
                    <DoubleAnimation Duration="0:0:0.4" To="60" Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="border" d:IsOptimized="True"/>
                </Storyboard>
            </Border.Resources>
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseLeave">
                    <ei:ControlStoryboardAction Storyboard="{StaticResource collapse}"/>
                </i:EventTrigger>
                <i:EventTrigger EventName="MouseEnter">
                    <ei:ControlStoryboardAction Storyboard="{StaticResource expand}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
            <StackPanel Height="32" Width="26">
                <TextBlock Text="{Binding Name}"/>
                <TextBlock Text="{Binding Order}"/>
            </StackPanel>
        </Border>
    </DataTemplate>