I am playing for the first time with Expression Blend. I made a very simple overlay grid that occupies all the screen space.
<!-- phone application page -->
<Grid x:Name="LayoutRoot">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
</Grid>
<TextBlock Grid.Row="0" Text="Some Content" />
<TextBlock Grid.Row="1" Text="Some Other Content />
<Grid x:Name="Overlay" Grid.RowSpan="2" Background="Black" Opacity="0" Visibility="Collapsed">
<TextBlock Text="Loading..." />
<toolkit:PerformanceProgressBar x:Name="ProgressBar" IsIndeterminate="False" />
</Grid>
</Grid>
I want the overlay grid to have 2 states:
where LoadingState:
NotLoadingState (basically what it is set as default in xaml):
The time between transitions: 0.5s
I am triggering the states in code-behind like this:
private void VmPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == ListViewModel.IsLoadingPropertyName)
{
if (_vm.IsLoading)
{
VisualStateManager.GoToState(this, LoadingStatePropertyName, true);
}
else
{
VisualStateManager.GoToState(this, NotLoadingStatePropertyName, true);
}
}
}
Yet as simple as the code above looks I couldn't get the transitions to work. Changing the state to LoadingState works, and I get a nice Opacity animation, but it doesn't the other way around (LoadingState -> NotLoadingState) - the Overlay Grid just disappears without any animation. I am guessing that's because the Visibility gets set to Collapsed. I've been trying to come up with something in Expression Blend but nothing worked so far.
Here's th requested generated source:
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="LoadingStateGroup">
<VisualStateGroup.Transitions>
<VisualTransition From="LoadingState" GeneratedDuration="0" To="NotLoadingState">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Overlay">
<EasingDoubleKeyFrame KeyTime="0" Value="0.8"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Overlay">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:0.5">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
<VisualTransition From="NotLoadingState" GeneratedDuration="0" To="LoadingState">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Overlay">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:0.5">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Overlay">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0.795"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
<VisualTransition GeneratedDuration="0"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="LoadingState">
<Storyboard>
<DoubleAnimation Duration="0" To="0.795" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Overlay" d:IsOptimized="True"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Overlay">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="NotLoadingState">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Overlay">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Overlay" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
What you need is Fluid Layout. It's specifically designed to solve this problem. You can read more here (good read, if a bit long) and the corresponding samples are here. There's even a Windows Phone 7 specific tutorial over here.