Loupe

[WP8] Gérer l’orientation grâce aux VisualState

 

Dans cet article, nous allons voir une méthode très simple pour basculer d’une vue Portrait en Paysage…et inversement. On va s’appuyer pour cela sur les VisualState, qui vont nous permettre d’afficher le contenu qu’il convient.

Voilà comment cela va se traduire dans le code :

  • Création d’une nouvelle classe qui hérite de la classe PhoneApplicationPage
  • Abonnement aux évènements OrientationChanged et SizeChanged
  • Déclenchement du VisualState en fonction de l’orientation

Ma nouvelle classe de base pour mes pages :

public class LayoutAwarePage : PhoneApplicationPage
{
    public LayoutAwarePage()
    {
        OrientationChanged += LayoutAwarePageOrientationChanged;
        SizeChanged += LayoutAwarePageSizeChanged;
    }

    void LayoutAwarePageSizeChanged(object sender, SizeChangedEventArgs e)
    {
        ChangeOrientationDisplay(sender, Orientation);
    }

    public bool IsSimplifyOrientationMode
    {
        get { return (bool)GetValue(IsSimplifyOrientationModeProperty); }
        set { SetValue(IsSimplifyOrientationModeProperty, value); }
    }

    public static readonly DependencyProperty IsSimplifyOrientationModeProperty =
        DependencyProperty.Register("IsSimplifyOrientationMode", typeof(bool), typeof(LayoutAwarePage),
		 new PropertyMetadata(null));

    void LayoutAwarePageOrientationChanged(object sender, OrientationChangedEventArgs e)
    {
        ChangeOrientationDisplay(sender, e.Orientation);
    }

    void ChangeOrientationDisplay(object sender, PageOrientation orientation)
    {
        var control = sender as LayoutAwarePage;

        if (IsSimplifyOrientationMode)
        {
            if (orientation == PageOrientation.Portrait
                || orientation == PageOrientation.PortraitUp
                || orientation == PageOrientation.PortraitDown)
            {
                VisualStateManager.GoToState(control, "Portrait", false);
            }
            else if (orientation == PageOrientation.Landscape
                        || orientation == PageOrientation.LandscapeLeft
                        || orientation == PageOrientation.LandscapeRight)
            {
                VisualStateManager.GoToState(control, "Landscape", false);
            }
        }
        else
        {
            if (orientation == PageOrientation.Portrait)
            {
                VisualStateManager.GoToState(control, "Portrait", false);
            }
            else if (orientation == PageOrientation.PortraitUp)
            {
                VisualStateManager.GoToState(control, "PortraitUp", false);
            }
            else if (orientation == PageOrientation.PortraitDown)
            {
                VisualStateManager.GoToState(control, "PortraitDown", false);
            }
            else if (orientation == PageOrientation.Landscape)
            {
                VisualStateManager.GoToState(control, "Landscape", false);
            }
            else if (orientation == PageOrientation.LandscapeLeft)
            {
                VisualStateManager.GoToState(control, "LandscapeLeft", false);
            }
            else if (orientation == PageOrientation.LandscapeRight)
            {
                VisualStateManager.GoToState(control, "LandscapeRight", false);
            }
        }
    }
}

On peut noter la création d’une DependencyProperty nommée IsSimplifyOrientationMode pour avoir une gestion simplifié de l’orientation.

Pour l’utiliser rien de plus simple :

<fwk:LayoutAwarePage x:Class="IS.OrientationPage"
                     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                     xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
                     xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
                     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                     SupportedOrientations="PortraitOrLandscape"
                     xmlns:fwk="clr-namespace:IS.Phone.Xaml.Controls;assembly=IS.Phone.Xaml"
                     IsSimplifyOrientationMode="True">

    <Grid x:Name="LayoutRoot">
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="Orientation">
                <VisualState x:Name="Portrait">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
                                                       Storyboard.TargetName="PortraitView">
                            <DiscreteObjectKeyFrame KeyTime="0">
                                <DiscreteObjectKeyFrame.Value>
                                    <Visibility>Visible</Visibility>
                                </DiscreteObjectKeyFrame.Value>
                            </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
                                                       Storyboard.TargetName="LandscapeView">
                            <DiscreteObjectKeyFrame KeyTime="0">
                                <DiscreteObjectKeyFrame.Value>
                                    <Visibility>Collapsed</Visibility>
                                </DiscreteObjectKeyFrame.Value>
                            </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Landscape">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
                                                       Storyboard.TargetName="PortraitView">
                            <DiscreteObjectKeyFrame KeyTime="0">
                                <DiscreteObjectKeyFrame.Value>
                                    <Visibility>Collapsed</Visibility>
                                </DiscreteObjectKeyFrame.Value>
                            </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
                                                       Storyboard.TargetName="LandscapeView">
                            <DiscreteObjectKeyFrame KeyTime="0">
                                <DiscreteObjectKeyFrame.Value>
                                    <Visibility>Visible</Visibility>
                                </DiscreteObjectKeyFrame.Value>
                            </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

        <!-- Display only in portrait mode -->
        <Grid x:Name="PortraitView">
            <TextBlock Text="Portrait" />
        </Grid>

        <!-- Display only in landscape mode -->
        <Grid x:Name="LandscapeView">
            <TextBlock Text="Landscape" />
        </Grid>
    </Grid>

</fwk:LayoutAwarePage>

On pourra, par la suite, rajouter une animation de transition entre les deux états pour donner un effet sympa Sourire

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus