0

我创建了一个用于 ListBoxItems 的 DataTemplate。我创建了一个彩色动画,其中项目的背景颜色从绿色开始,然后在一段时间内慢慢变成红色。

问题是这样的——我需要根据包含在 ListBox 项目中的时间戳来设置 Storyboard Seek Offset(例如:一个项目突然填充了 ListBox,其颜色动画应该被移动,比如动画 17​​ 秒)。当我最初创建它时,我认为这很容易,因为我只需将 Offset 绑定到一个值转换器,该转换器根据绑定项的时间戳返回 TimeSpan 值。但是,正如我发现的那样,您不能对 SeekStoryboard Offset 执行数据绑定。

任何人都可以提出一种解决方法或者一些可以解决这个问题的代码隐藏魔法吗?此列表框将包含很少的项目(最多可能 5 个),因此遍历集合并以编程方式获取情节提要资源并手动设置偏移量不会太耗时。但是,我不确定如何执行此操作,因为我的 Listbox 是由自定义对象而不是 ListBoxItem 类型的 UIElement 填充的。

    <DataTemplate x:Key="TicketTemplate">
        <DataTemplate.Resources>
            <Storyboard x:Key="OnLoaded1">
                <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="border">
                    <EasingColorKeyFrame KeyTime="0" Value="Lime"/>
                    <EasingColorKeyFrame KeyTime="0:15:0" Value="Yellow"/>
                    <EasingColorKeyFrame KeyTime="0:30:0" Value="Orange"/>
                    <EasingColorKeyFrame KeyTime="0:45:0" Value="Red"/>
                </ColorAnimationUsingKeyFrames>
            </Storyboard>
        </DataTemplate.Resources>
        <Border x:Name="border" BorderBrush="Black" Margin="1" BorderThickness="2" CornerRadius="10" Padding="5,1">
            <Border.Background>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="GhostWhite"  Offset="1"/>
                    <GradientStop Color="GhostWhite"/>
                </LinearGradientBrush>
            </Border.Background>
            <Grid>
                <!-- ELEMENTS FOR LISTBOXITEM TEMPLATE -->
            </Grid>
        </Border>
        <DataTemplate.Triggers>
            <EventTrigger RoutedEvent="FrameworkElement.Loaded" SourceName="border">
                <BeginStoryboard x:Name="WarningStory" Storyboard="{StaticResource OnLoaded1}"/>
                <SeekStoryboard BeginStoryboardName="WarningStory" Offset="0" <!-- cannot databind to Offset =( --> Origin="BeginTime" />
            </EventTrigger>
        </DataTemplate.Triggers>
    </DataTemplate>
4

1 回答 1

2

有一种解决方法可以启用与不是依赖属性的属性的绑定。它要求拥有目标属性的类派生自DependencyObject,幸运的是,对于SeekStoryboard.

您将使用设置实际目标属性的 a创建附加的辅助属性。PropertyChangedCallback

public static class SeekStoryboardExt
{
    public static readonly DependencyProperty BindableOffsetProperty =
        DependencyProperty.RegisterAttached(
            "BindableOffset", typeof(TimeSpan), typeof(SeekStoryboardExt),
            new PropertyMetadata(BindableOffsetPropertyChanged));

    public static TimeSpan GetBindableOffset(DependencyObject obj)
    {
        return (TimeSpan)obj.GetValue(BindableOffsetProperty);
    }

    public static void SetBindableOffset(DependencyObject obj, TimeSpan value)
    {
        obj.SetValue(BindableOffsetProperty, value);
    }

    private static void BindableOffsetPropertyChanged(
        DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        var seekStoryboard = obj as SeekStoryboard;
        if (seekStoryboard != null)
        {
            seekStoryboard.Offset = (TimeSpan)e.NewValue;
        }
    }
}

You would now bind the helper property instead of the target property:

<SeekStoryboard local:SeekStoryboardExt.BindableOffset="{Binding ...}" .../>
于 2013-02-23T22:58:39.490 回答