3

We're writing a Prism based Silverlight application and we've got a whole bunch of pages in separate modules.

The transition between the pages is handled via navigation events and each module has the following methods implemented to show the page when navigated to and hide it when navigated from:

public void Show()
{
    VisualStateManager.GoToState(this, "ShowState", true);
}

public void Hide()
{
    VisualStateManager.GoToState(this, "HideState", true);
}

At the moment "ShowState" and "HideState" are defined in each module's XAML file so are duplicated far too many times.

<Grid x:Name="LayoutRoot">
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="VisualStates">
            <VisualState x:Name="ShowState">
                ...
            </VisualState>
            <VisualState x:Name="HideState">
                ...
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>

Where ... represents the Storyboard for each transition.

I've just spotted an error in the Storyboard definitions and at the moment I'm going to have to replicate the fix across all the files. It would be better if there was only one definition of the Storyboard which could be referenced in each file.

I've searched all morning for the right syntax but have had no luck what so ever.

How can I share this VisualStateManager between all our XAML files?

ChrisF
  • 134,786
  • 31
  • 255
  • 325
  • It seems like you want to encapsulate the 'behavior' within a custom Control. That way you simply reuse the control as needed, which will encapsulate your Storyboard therefore providing a single point of reference to fix issues as they arise. My guess is this is something akin to an Expander or the like; providing functionality common to any child within that container. – Aaron McIver Dec 06 '10 at 14:40

1 Answers1

2
<Storyboard x:Key="ShowStoryboard">
    <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="glow" Storyboard.TargetProperty="(UIElement.Opacity)">
        <SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0"/>
    </DoubleAnimationUsingKeyFrames>
</Storyboard>

<VisualState x:Name="ShowState">
    <BeginStoryboard Storyboard="{StaticResource ShowStoryboard}"/>
</VisualState>

Referencing your Storyboard within XAML can be done as seen above. With the top most portion being a Storyboard stored as a Resource somewhere. After that you should be able to use the BeginStoryboard reference within your VisualState.

EDIT: The above appears possible within WPF however it is not possible in SL. As of current it does not appear the abilty to reuse a Storyboard or VisualState is possible in SL. You should still be able to achieve what you are trying to do by encapsulating the VisualStateManager behavior within a style applied to a custom control. This would provide you the single point of failure you are looking for.

Aaron McIver
  • 24,527
  • 5
  • 59
  • 88
  • I was hoping to reference the entire `VisualStateManager` but having the `Storyboard` definitions in one place would do ;) – ChrisF Dec 06 '10 at 15:37
  • 1
    This doesn't work. `BeginStoryboard` isn't recognised as valid XAML and if I just do `` I get an error on initialisation. – ChrisF Dec 07 '10 at 09:38
  • @ChrisF BeginStoryboard is indeed active within SL; however it has limited avail within Triggers and perhaps within a VisualState not acceptable (it is in WPF), let me see what else I can drum up... – Aaron McIver Dec 07 '10 at 14:47
  • @ChrisF Doesn't look possible with SL...however what is the reason for not creating a custom control and then defining a style containing the needed VSM work and then reuse the custom control? – Aaron McIver Dec 07 '10 at 14:59
  • I'm beginning to think that custom control is the way to go. Having the VSM/Storyboard as a resource would have been a little easier though ;). If you want to update your answer, I'll accept it. – ChrisF Dec 07 '10 at 15:16