简体   繁体   中英

Binding property to Storyboard value in XAML

I have a Storyboard animation that looks like this:

<Grid Name="Choice" VerticalAlignment="Stretch" Width="400">
    <Interactivity:Interaction.Behaviors>
        <Core:EventTriggerBehavior EventName="Tapped">
            <Media:ControlStoryboardAction>
                <Media:ControlStoryboardAction.Storyboard>
                    <Storyboard x:Name="Animation">
                        <DoubleAnimationUsingKeyFrames EnableDependentAnimation="True" Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="Choice">
                            <EasingDoubleKeyFrame KeyTime="0" Value="{Binding Path=InitialWidth}"/>
                            <EasingDoubleKeyFrame KeyTime="0:0:1" Value="{Binding Path=FinalWidth}" />
                        </DoubleAnimationUsingKeyFrames>
                    </Storyboard>
                </Media:ControlStoryboardAction.Storyboard>
            </Media:ControlStoryboardAction>
        </Core:EventTriggerBehavior>
    </Interactivity:Interaction.Behaviors>
    <Image HorizontalAlignment="Center" VerticalAlignment="Center" Source="{Binding Path=Image}" Stretch="UniformToFill" />
</Grid>

The initial value I set in the properties InitialWidth and FinalWidth seems to be correct, but if I change later on, they are not updated and are 0 . I read somewhere that it's not possible to bind properties to Storyboard values at runtime, but I did not find any official document stating that.
My question is, can I bind properties to Storyboard values? If so, what do I need to change?

I can't test this, so just take it as a suggestion for something that "might work". The idea is to create a "proxy" object in your page resources, and then reference it using a StaticResource binding.

The proxy is just a DependencyObject that contains the properties you're interested in binding:

public class ProxyObject : DependencyObject
{
    public double InitialWidth
    {
        get { return (double)GetValue(InitialWidthProperty); }
        set { SetValue(InitialWidthProperty, value); }
    }
    public static readonly DependencyProperty InitialWidthProperty =
        DependencyProperty.Register("InitialWidth", typeof(double), typeof(ProxyObject), new PropertyMetadata(0));

    public double FinalWidth
    {
        get { return (double)GetValue(FinalWidthProperty); }
        set { SetValue(FinalWidthProperty, value); }
    }
    public static readonly DependencyProperty FinalWidthProperty =
        DependencyProperty.Register("FinalWidth", typeof(double), typeof(ProxyObject), new PropertyMetadata(0));
}

Now instantiate it in your page resources, with bindings to your view model:

<Grid Name="Choice">
    <Grid.Resources>
        <ResourceDictionary>
            <local:ProxyObject x:Name="proxy"
                InitialWidth="{Binding InitialWidth}" FinalWidth="{Binding FinalWidth}" />
        </ResourceDictionary>
    </Grid.Resources>
    ...
</Grid>

Then you can reference this as a static resource from the timeline elements:

<EasingDoubleKeyFrame KeyTime="0" 
    Value="{Binding Source="{StaticResource proxy},Path=InitialWidth}" />
<EasingDoubleKeyFrame KeyTime="0:0:1" 
    Value="{Binding Source="{StaticResource proxy},Path=InitialWidth}" />

I have successfully used something similar in a Silverlight (visual state storyboards in a control template), but I'm not sure if it will apply to your scenario.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM