Search code examples
c#xamluser-controlswindows-10-mobile

how to use "visualstate" to modify child usercontrol's status in xaml?


I'm doing something windows 10 UWP app development,and I got a problem,Thanks all for help,blew is my code:

In MainPage.xaml

<Grid  Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Pivot Style="{StaticResource fuckpivot}" SelectionChanged="Pivot_SelectionChanged">
        <PivotItem>
            <PivotItem.Header>
                <local:test Label="item 3" Glyph="&#xE723;" />
            </PivotItem.Header>
            <Rectangle 
                      x:Name="MyAnimatedRectangle"
                      Width="100" Height="100" Fill="Blue" />
        </PivotItem>
        <PivotItem>
            <PivotItem.Header>
                <local:test Label="item 2" Glyph="&#xE723;" HighLight="Transparent"/>
            </PivotItem.Header>
            <!--<Rectangle x:Name="MyTest" Width="100" Height="100" Fill="red"/>-->
        </PivotItem>
    </Pivot>

</Grid>

and my "testControl":

   <Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="10"/>
    </Grid.RowDefinitions>
    <StackPanel Grid.Row="0">
        <FontIcon
                        HorizontalAlignment="Center"
                        Margin="0,12,0,0"
                        Glyph="{Binding Glyph}"
                        FontSize="16" />
        <TextBlock
                        FontFamily="Segoe UI"
                        Text="{Binding Label}"
                        Style="{StaticResource CaptionTextBlockStyle}"
                        LineStackingStrategy="BlockLineHeight"
                        LineHeight="14"
                        MaxLines="2"
                        IsTextScaleFactorEnabled="False"
                        TextAlignment="Center"
                        HorizontalAlignment="Center"
                        Margin="2,5,2,7" />
    </StackPanel>
    <Grid Grid.Row="1">
        <Border BorderThickness="0,0,0,2" VerticalAlignment="Bottom" BorderBrush="Red"/>
    </Grid>
</Grid>

So, my question is :how to change the highlight color in the child UserControl named"test"?(when pivot change to the current Index, how to write the visual state?)


Solution

  • I've tested it on WP8.1 RunTime, but in this case I believe that it hadn't changed that much. The sample below is using VisualStateManager to change the Label.Foreground to Green. Code is mostly in XAML and goes like this:

    MainPage:

    <Grid  Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Pivot SelectionChanged="Pivot_SelectionChanged">
            <PivotItem>
                <PivotItem.Header>
                    <local:testControl Label="item 3" Glyph="&#xE723;" />
                </PivotItem.Header>
                <Rectangle 
                      x:Name="MyAnimatedRectangle"
                      Width="100" Height="100" Fill="Blue" />
            </PivotItem>
            <PivotItem>
                <PivotItem.Header>
                    <local:testControl Label="item 2" Glyph="&#xE723;"/>
                </PivotItem.Header>
            </PivotItem>
        </Pivot>
    </Grid>
    

    testControl:

    <Grid>        
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="SelectionStates">
                <VisualState x:Name="Unselected"/>
                <VisualState x:Name="Selected">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Foreground" Storyboard.TargetName="MyLabel">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Green"/>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="10"/>
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0">
            <FontIcon   HorizontalAlignment="Center" Margin="0,12,0,0" Glyph="{Binding Glyph}" FontSize="16" />
            <TextBlock x:Name="MyLabel" FontFamily="Segoe UI" Text="{Binding Label}" LineStackingStrategy="BlockLineHeight" LineHeight="14"
                       TextAlignment="Center" HorizontalAlignment="Center" Margin="2,5,2,7" />
        </StackPanel>
        <Grid Grid.Row="1">
            <Border BorderThickness="0,0,0,2" VerticalAlignment="Bottom" BorderBrush="Red"/>
        </Grid>
    </Grid>
    

    To make this work you will only have to change VisualStates when pivot selection changes - this goes in MainPage's code behind:

    private void Pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (e.RemovedItems.Count > 0)
            VisualStateManager.GoToState((e.RemovedItems.First() as PivotItem).Header as testControl, "Unselected", true);
        if (e.AddedItems.Count > 0)
            VisualStateManager.GoToState((e.AddedItems.First() as PivotItem).Header as testControl, "Selected", true);
    }
    

    You should also find more help at MSDN and probably more at some blogs and articles.