DataTemplate的Silverlight故事板

时间:2011-11-07 00:26:55

标签: c# silverlight animation storyboard

我正在使用水平列表,当您将鼠标悬停在水平列表上时,每个项目都会展开。

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

ATTEMPT 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'.

ATTEMPT 2 我现在使用MouseEnter事件以不同方式实现它。由于尝试1失败。

<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();
        }

然而,现在只有当鼠标悬停在它上面时才会扩展,当我鼠标离开时它会停止并且它不会崩溃。我在语法上设置故事板的原因还在于,当我定义两个故事板并且只是重新分配并将其运行到不同的项目时,当我将鼠标移动到所有列表项时,它看起来非常糟糕。

1 个答案:

答案 0 :(得分:2)

不幸的是,Silverlight仅支持Loaded EventTrigger。

解决方法非常简单,请使用Behaviors。您只需要使用ControlStoryboardActionGoToStateAction来触发动画。

像这样,

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

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

<强>更新

你最好在你的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>