【问题标题】:Silverlight Storyboard of DataTemplateDataTemplate 的 Silverlight 故事板
【发布时间】:2011-12-23 07:26:20
【问题描述】:

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

我已经阅读了一些教程,并且能够使用 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 事件以不同的方式实现它。由于尝试 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();
        }

但是,现在它只会在我将鼠标悬停在它上面时展开,当我离开鼠标时它会停止并且它不会运行折叠。另外,我以编程方式设置情节提要的原因是,当我定义两个情节提要并只是将其重新分配并运行到不同的项目时,当我在所有列表项上移动鼠标时看起来很糟糕。

【问题讨论】:

  • 你确定它适用于单个元素吗?据我所知 Silverlight 仅支持 Loaded EventTrigger。
  • 对于单个元素,我实际上使用 EventHandlers - &lt;Border BorderBrush="Gray" HorizontalAlignment="Stretch" Width="60" MouseEnter="Expand" MouseLeave="Collapse"&gt;。我会尝试更改它,使其不使用 EventTrigger。
  • 就是这样,不幸的是,您只能在 Silverlight 中使用 Loaded 事件触发器,但我会向您展示一个解决方法作为答案
  • @Xin 我又一次尝试它几乎就在那里 - 我能感觉到它......还没有完全在那里。
  • 我再次更新了我的答案......使用更简单的版本。 :)

标签: c# silverlight animation storyboard


【解决方案1】:

很遗憾,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>

【讨论】:

  • 我有你的解决方案,我会不断收到'ControlStoryboardAction' was not found because 'http://schemas.microsoft.com/expression/2010/interactions' is an unknown namespace。我的项目中确实引用了 Microsoft.Expression.Interactions 和 System.Windows.Interactivity。所以我不确定我做错了什么。
  • 这很奇怪,你安装了 Expression Blend 吗?
  • 是的,EB 4。我使用了其中的 dll。然而同样的问题。是否有任何其他的体面或只是这两个?
  • 不...我不这么认为,您如何从 Blend 4 创建一个新项目,然后在“资产”面板中,输入 ControlStoryboardAction,然后将其拖放到任何控制,看看它是否抱怨?
  • @JustinXL 啊,就是这样,我使用的是 WPF 而不是 SL。感谢您的信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-14
  • 2012-04-12
  • 2011-07-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多