Search code examples
xamluwpuwp-xamlvisualstatemanager

Why the VisualStateManager didn't work?


<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
   <Grid>
       <Grid.ColumnDefinitions>
           <ColumnDefinition Width="auto"/>
           <ColumnDefinition Width="*"/>
           <ColumnDefinition Width="auto"/>`enter code here`
       </Grid.ColumnDefinitions>
       <VisualStateManager.VisualStateGroups>
           <VisualStateGroup>
               <VisualState x:Name="Narrow">
                   <VisualState.StateTriggers>
                       <AdaptiveTrigger MinWindowWidth="0"/>
                   </VisualState.StateTriggers>
                   <VisualState.Setters>
                       <Setter Target="SliderProgress.Visibility" Value="Collasped"/>
                       <Setter Target="TimeProgress.Visibility" Value="Visible"/>
                       <Setter Target="btnPlayList.Visibility" Value="Collasped"/>
                   </VisualState.Setters>
               </VisualState>
               <VisualState x:Name="Wide">
                   <VisualState.StateTriggers>
                       <AdaptiveTrigger MinWindowWidth="600"/>
                   </VisualState.StateTriggers>
                   <VisualState.Setters>
                       <Setter Target="SliderProgress.Visibility" Value="Visible"/>
                       <Setter Target="TimeProgress.Visibility" Value="Collapsed"/>
                       <Setter Target="btnPlayList.Visibility" Value="Visible"/>
                   </VisualState.Setters>
               </VisualState>
           </VisualStateGroup>
       </VisualStateManager.VisualStateGroups>
       <Image Grid.Column="0" 
              Height="70" 
              Width="70"/>
       <!--PlayProgress-->
       <StackPanel Grid.Column="1"
                   Margin="10,0,0,0">
           <TextBlock Text="Title"/>
           <Slider Name="SliderProgress"
                   Visibility="Collapsed"/>
           <StackPanel Orientation="Horizontal"
                       Margin="10,10,0,0"
                       Name="TimeProgress"
                       Visibility="Visible">
               <TextBlock Name="CurrentTime"
                          Text="CurrentTime"/>
               <TextBlock Text=" / "/>
               <TextBlock Name="TotleTime"
                          Text="TotleTime"/>
           </StackPanel>
       </StackPanel>
       <!--PlayProgress Over-->
       <!--PlayControlButton-->
       <StackPanel Grid.Column="2" 
                   Orientation="Horizontal"
                   Grid.ColumnSpan="1">
           <Button Style="{StaticResource CtrlButton}"
                   Content="&#xE0E2;">
           </Button>
           <Button Style="{StaticResource CtrlButton}"
                   Content="&#xE102;">
           </Button>
           <Button Style="{StaticResource CtrlButton}"
                   Content="&#xE0E3;">
           </Button>
           <Button Name="btnPlayList"
                   Style="{StaticResource CtrlButton}"
                   Content="&#xE142;"
                   Visibility="Collapsed">
           </Button>
       </StackPanel>
       <!--PlayControlButton Over-->
   </Grid>

Please help me understand why the VisualStateManager didn't work, it really troubles me. If I remove the second Grid, XAML Designer shows an error and when I run the app, it will show the SliderProgress and TimeProgress hide.


Solution

  • There are two problems in your code.

    Firstly, the VisualStateManager.VisualStateGroups attached property should be under the root element of your Page. So you can put your VisualStateManager under the root Gird like:

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup>
                <VisualState x:Name="Narrow">
                    ...
                </VisualState>
                <VisualState x:Name="Wide">
                    ...
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    
        <Grid>
            ...
        </Grid>
    </Grid>
    

    Secondly, the property value type of Visibility is Visibility, an enumeration. To animate values that are enumerations, you must use a DiscreteObjectKeyFrame. (You also use this technique for Boolean values).

    So you can change your code as the following. Then your VisualStateManager should be able to work.

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup>
                <VisualState x:Name="Narrow">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="0" />
                    </VisualState.StateTriggers>
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="SliderProgress" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="TimeProgress" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="btnPlayList" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Wide">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="600" />
                    </VisualState.StateTriggers>
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="SliderProgress" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="TimeProgress" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="btnPlayList" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    
        <Grid>
            ...
        </Grid>
    </Grid>