VisualState不适用于布局的可见性

时间:2015-04-28 13:20:33

标签: wpf xaml windows-phone-8 windows-8 windows-8.1

在通用应用程序(MVVM架构)中,我的可视状态代码不适用于布局的可见性(使用进度条)。请告诉我我哪里出错了。

我跟着这个Link

XAML中的VisualState:

<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>

VIEWMODEL上的C#代码:

 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();
    }

1 个答案:

答案 0 :(得分:1)

为了使Visual States能够工作,你需要在Grid下面添加不在Page下面的网格。

不要担心它是否应该在页面上(听起来是逻辑),它会起作用。

现在以下代码可以运行:

我已将CurrentState设置如下:

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

我不知道你为什么使用ref。

为了测试我添加的状态:

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

(我删除了z-index以便能够点击按钮)

现在初始化:

在未加载页面之前,状态不会“更改”。所以你需要进行第一次更改以设置basestate:

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

总结所有这些可能是更有趣的绑定IsActive,但可能你需要做一个更大的状态逻辑。