Russell Bearden
Russell Bearden

Reputation: 178

How to reuse a single literal value to initialize multiple different types in a XAML resource dictionary?

Many types in XAML have converters that accept identical format inputs, but the types themselves are not implicitly compatible. For instance "0:0:4" can be a Duration or a Keytime among many others. And sometimes I'd like to use the same value for these sort of things. For instance perhaps I have a KeyTime that starts right after the Duration of another animation:

<Duration x:Key="Foo">0:0:4</Duration>
<KeyTime x:Key="Bar">0:0:4</KeyTime>

The problem with this is that there's no way to express the contract that these values should be the same. So what I'd like is something along the lines of:

<system:String x:Key="AnimationTime">0:0:4</system:String>
<Duration x:Key="Foo">[AnimationTime]</Duration>
<KeyTime x:Key="Bar">[AnimationTime]</KeyTime>

But I'm uncertain of the syntax for this. I assume I need to invoke the converters for the Duration/Keytime but I'm finding XAML syntax is not always the most intuitive.

Upvotes: 1

Views: 173

Answers (1)

Clemens
Clemens

Reputation: 128097

Instead of directly using StaticResource like

KeyTime="{StaticResource AnimationTime}"

you may often use a Binding with the resource as Source object like

KeyTime="{Binding Source={StaticResource AnimationTime}}"

and thus benefit from automatic type conversion.

An example:

<Window.Resources>
    <system:String x:Key="AnimationTime">0:0:4</system:String>

    <Storyboard x:Key="ExampleStoryboard">
        <DoubleAnimation To="1"
            Storyboard.TargetProperty="Opacity"
            Duration="{Binding Source={StaticResource AnimationTime}}"/>

        <ObjectAnimationUsingKeyFrames
            Storyboard.TargetProperty="Background">
            <DiscreteObjectKeyFrame
                KeyTime="{Binding Source={StaticResource AnimationTime}}"
                Value="{x:Static Brushes.Green}"/>
        </ObjectAnimationUsingKeyFrames>
    </Storyboard>
</Window.Resources>

<Grid Background="Red" Opacity="0">
    <Grid.Triggers>
        <EventTrigger RoutedEvent="Loaded">
            <BeginStoryboard
                Storyboard="{StaticResource ExampleStoryboard}"/>
        </EventTrigger>
    </Grid.Triggers>
</Grid>

Upvotes: 2

Related Questions