Состояния раскадровки, свойство перехода и видимости

Я впервые играю с 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 для этого, но у меня не установлено на этом компьютере.

Другие вопросы по тегам