2015-04-28 3 views
0

В универсальных приложениях (архитектура MVVM) мой визуальный код состояния не работает для видимости макета (с индикатором прогресса). Пожалуйста, сообщите мне, где я ошибся.VisualState не работает для видимости макета

И я следовал этому Link

В VisualState в XAML:

<Page 
x:Class="Carrot_Windows.CarrotLoginPage" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:local="using:Carrot_Windows" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
mc:Ignorable="d" 
xmlns:i="using:Microsoft.Xaml.Interactivity" 
xmlns:core="using:Microsoft.Xaml.Interactions.Core" 
DataContext="{Binding Login, Mode=TwoWay, Source={StaticResource Locator}}"> 
<VisualStateManager.VisualStateGroups> 
    <VisualStateGroup x:Name="Progress_layout"> 
     <VisualState x:Name="BaseState"> 
      <Storyboard> 
       <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="ProgressGrid"> 
        <DiscreteObjectKeyFrame KeyTime="0"> 
         <DiscreteObjectKeyFrame.Value> 
          <Visibility>Collapsed</Visibility> 
         </DiscreteObjectKeyFrame.Value> 
        </DiscreteObjectKeyFrame> 
       </ObjectAnimationUsingKeyFrames>      
      </Storyboard> 
     </VisualState> 
     <VisualState x:Name="ProgressState"> 
      <Storyboard> 
       <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ProgressGrid"> 
        <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/> 
       </ObjectAnimationUsingKeyFrames> 
      </Storyboard> 
     </VisualState>   
    </VisualStateGroup> 
</VisualStateManager.VisualStateGroups> 

<i:Interaction.Behaviors> 
    <core:DataTriggerBehavior Binding="{Binding CurrentState}" 
            ComparisonCondition="Equal" Value="BaseState"> 
     <core:GoToStateAction StateName="BaseState" /> 
    </core:DataTriggerBehavior> 
    <core:DataTriggerBehavior Binding="{Binding CurrentState}" 
            ComparisonCondition="Equal" Value="ProgressState"> 
     <core:GoToStateAction StateName="ProgressState" /> 
    </core:DataTriggerBehavior> 
</i:Interaction.Behaviors> 

Мастер компоновки

<Grid x:Name="Grid_Master" Background="White"> 

    // THE LAYOUT ON WHICH VISUAL STATE APPLIED 
    <Grid x:Name="ProgressGrid" Background="Black" Opacity=".7" Grid.RowSpan="5" Grid.ColumnSpan="3" Canvas.ZIndex="1" > 
     <ProgressRing Height="90" Width="90" HorizontalAlignment="Center" VerticalAlignment="Center" IsActive="True" /> 
    </Grid> 

    <Viewbox Grid.Column="1" Grid.Row="3" > 
     <Border Background="LightGray" Width="520" Height="300" > 
      <Grid> 
       //Do something 
      </Grid> 
     </Border> 
    </Viewbox> 

</Grid> 

C# код на ViewModel:

private enum ViewModelState 
    { 
     BaseState, 
     ProgressState 
    } 

    private string currentState; 
    public string CurrentState 
    { 
     get { return currentState; } 
     set 
     { 
      this.Set(ref currentState, value); 
      RaisePropertyChanged("CurrentState"); 
     } 
    } 

    private void LoginButtonClicked() 
    { 
     CurrentState = ViewModelState.ProgressState.ToString(); 
    } 
+0

Я думаю, что есть проблема в Value = "ProgressGrid"> Это не называется ProgressState? –

+0

@juan Pablo Garcio Coello да, спасибо, но визуальное состояние BaseState также не срабатывает. –

+0

Где в XAML вы добавили VisualState и поведение, ниже ? –

ответ

1

Чтобы заставить Visual States работать, вы должны добавить ниже Grid, а не ниже страницы, также разместите взаимодействие ниже Grid.

Не волнуйтесь, если это должно быть на странице (это звучит логично), это сработает.

А теперь следующий код работает:

Я поставил CurrentState как следующее:

private string currentState; 
    public string CurrentState 
    { 
     get { return currentState; } 
     set 
     { 
      currentState = value; 
      NotifyPropertyChanged(); 
     } 
    } 

Я не знаю, почему вы используете реф.

И, чтобы проверить состояние я добавил:

private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     CurrentState = CurrentState == "BaseState" ? "ProgressState" : "BaseState"; 
    } 

(я удалить Z-индекс, чтобы иметь возможность нажать на кнопку)

Теперь инициализацию:

Пока страница не является не загружено, состояние не изменяется, поэтому вам необходимо сделать первое изменение, чтобы установить базовый уровень:

private async void Initialize() 
    { 
     await Task.Delay(100); 
     CurrentState = "ProgressState"; 
     CurrentState = "BaseState"; 
    } 

Итак, суммируя все это, возможно, более интересным является привязка IsActive, но вам может понадобиться сделать большую логику состояния.

+0

Нет, это не сработало. Я уже пробовал оба способа, добавив в Grid_Master и ProgressGrid (макет, для которого применяется визуальное состояние). –

+0

Я создам тестовый проект, позвольте мне проверить 5 мин –

+0

Я сделал тест со стандартным INotifyPropertyChanged, чтобы посмотреть в редакцию ответа –

Смежные вопросы