Состояния раскадровки, свойство перехода и видимости
Я впервые играю с Expression Blend. Я сделал очень простую оверлейную сетку, которая занимает все пространство экрана.
<!-- 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>
Я хочу, чтобы наложенная сетка имела 2 состояния:
- LoadingState
- NotLoadingState
где LoadingState:
- ProgressBar.IsIndeterminate = "True"
- Непрозрачность ="80"
- Видимость = "Видимый"
NotLoadingState (в основном то, что установлено по умолчанию в xaml):
- ProgressBar.IsIndeterminate = "False"
- Непрозрачность = "0"
- Видимость = "Свернутые"
Время между переходами: 0,5 с
Я запускаю состояния в коде позади так:
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);
}
}
}
Тем не менее, так просто, как выглядит приведенный выше код, я не смог заставить переходы работать. Изменение состояния на LoadingState работает, и я получаю хорошую анимацию Opacity, но это не наоборот (LoadingState -> NotLoadingState) - Overlay Grid просто исчезает без какой-либо анимации. Я предполагаю, что это потому, что Видимость установлена на Свернутый. Я пытался что-то придумать в Expression Blend, но пока ничего не получалось.
Вот запрашиваемый сгенерированный источник:
<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>
2 ответа
Что вам нужно, так это Fluid Layout. Он специально разработан для решения этой проблемы. Вы можете прочитать больше здесь (хорошее чтение, если немного долго), и соответствующие образцы здесь. Здесь даже есть специальное руководство по Windows Phone 7.
Вы правы, что переход немедленно переключает Видимость на Свернутый, поэтому вы не видите анимированную непрозрачность.
В Expression Blend вы можете создавать собственные переходы между двумя состояниями, что позволяет напрямую редактировать раскадровку, которая является переходом. После этого вы сможете создать раскадровку, которая оживит видимость в конце перехода.
Извините, я не могу дать больше советов о том, как использовать Blend для этого, но у меня не установлено на этом компьютере.