0

ListBoxItems に使用される DataTemplate を作成しました。アイテムの背景色が緑から始まり、時間の経過とともにゆっくりと赤に変わるカラー アニメーションを作成しました。

問題はこれです - ListBox の項目に含まれるタイムスタンプに応じて Storyboard Seek Offset を設定する必要があります (例: 項目が突然、カラー アニメーションを移動する必要がある ListBox に入力されます。たとえば、アニメーションの 17 秒後)。これを最初に作成したとき、バインディング アイテムのタイムスタンプに基づいて TimeSpan 値を返す値コンバーターに Offset をバインドするだけなので、これは非常に簡単だと思いました。しかし、私が発見したように、SeekStoryboard Offset へのデータバインディングを実行することはできません。

これを処理できる回避策またはコード ビハインド マジックを提案できる人はいますか? この Listbox には非常に少数のアイテム (多くても 5 つ) が含まれるため、コレクションを反復処理し、プログラムで Storyboard リソースを取得してオフセットを手動で設定するのにそれほど時間はかかりません。ただし、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

実際のターゲット プロパティを設定するを使用して、添付されたヘルパー プロパティを作成します。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;
        }
    }
}

ターゲット プロパティの代わりにヘルパー プロパティをバインドします。

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