Archive

Archive for mars 2010

[SL3] : 3D ControlRotator

Nous allons voir dans cet article comment réaliser un composant permettant d’afficher deux contrôles distincts via des rotations. Ce principe est utilisé pour les gadgets mac par exemple.

Voici ce que nous obtiendrons

L’énumération des directions disponibles

 
 /// <summary>
    /// Enumération définissant le sens de rotation du controle
    /// </summary>
    public enum RotateDirection
    {
        /// <summary>
        /// De la gauche vers la droite
        /// </summary>
        LeftToRight,
        /// <summary>
        /// De la droite vers la gauche
        /// </summary>
		RightToLeft,
        /// <summary>
        /// Tu haut vers le bas
        /// </summary>
		TopToBottom,
        /// <summary>
        /// Du bas vers le haut
        /// </summary>
		BottomToTop
    }

Realisation du controle de rotation

Les dependency properties

Crééons les DP permettant de déterminer :

  • L’élément de devant
  • L’élément de derrière
  • Si le controle effectue une rotation
  • La direction de la rotation
  • La durée de la rotation
  • Si le controle à la face avant en vue
   /// <summary>
        /// Définit la DP représentant le contenu de la face principale
        /// </summary>
        private static readonly DependencyProperty FrontContentProperty =
            DependencyProperty.Register(
            "FrontContent",
            typeof(UIElement),
            typeof(ContentControl3D),
            new PropertyMetadata(null));
        /// <summary>
        /// Définit la DP représentant si le controle est en train de faire une rotation
        /// </summary>
        private static readonly DependencyProperty IsRotatingProperty =
           DependencyProperty.Register(
           "IsRotating",
           typeof(Boolean),
           typeof(ContentControl3D),
           new PropertyMetadata(null));
        /// <summary>
        /// Définit la DP définissant si le controle affiche le controle de la face principale
        /// </summary>
        private static readonly DependencyProperty IsFrontInViewProperty =
          DependencyProperty.Register(
          "IsFrontInView",
          typeof(Boolean),
          typeof(ContentControl3D),
          new PropertyMetadata(true));
        /// <summary>
        /// Définit la DP représentant le contenu de la face cachée
        /// </summary>
        private static readonly DependencyProperty BackContentProperty =
           DependencyProperty.Register(
           "BackContent",
           typeof(UIElement),
           typeof(ContentControl3D),
           new PropertyMetadata(null));
        /// <summary>
        /// Définit la DP représentant la durée de l'animation de rotation (en ms)
        /// </summary>
        private static readonly DependencyProperty DurationProperty =
           DependencyProperty.Register(
           "Duration",
           typeof(Double),
           typeof(ContentControl3D),
           new PropertyMetadata(600.0));
        /// <summary>
        /// Définit la DP représentant le sens de rotation du controle
        /// </summary>
        private static readonly DependencyProperty DirectionProperty =
           DependencyProperty.Register(
           "Direction",
           typeof(RotateDirection),
           typeof(ContentControl3D),
           new PropertyMetadata(null));
  /// <summary>
        /// Obtient ou définit le ContentPresenter associé à la face principale
        /// </summary>
        public UIElement FrontContent
        {
            get
            {
                return (UIElement)GetValue(FrontContentProperty);
            }
            set
            {
                SetValue(FrontContentProperty, value);
            }
        }
        /// <summary>
        /// Obtient ou définit le ContentPresenter associé à la face cachée
        /// </summary>
        public UIElement BackContent
        {
            get
            {
                return (UIElement)GetValue(BackContentProperty);
            }
            set
            {
                SetValue(BackContentProperty, value);
            }
        }
        /// <summary>
        /// Obtient ou définit le sens de rotation du controle
        /// </summary>
        public RotateDirection Direction
        {
            get
            {
                return (RotateDirection)GetValue(DirectionProperty);
            }
            set
            {
                SetValue(DirectionProperty, value);
            }
        }
        /// <summary>
        /// Obtient ou définit si le controle est en train d'effectuer une rotation
        /// </summary>
        public Boolean IsRotating
        {
            get
            {
                return (Boolean)GetValue(IsRotatingProperty);
            }
            set
            {
                SetValue(IsRotatingProperty, value);
            }
        }
        /// <summary>
        /// Obtient ou définit la durée de l'animation de rotation
        /// </summary>
        public Double Duration
        {
            get
            {
                return (Double)GetValue(DurationProperty);
            }
            set
            {
                SetValue(DurationProperty, value);
            }
        }
        /// <summary>
        /// Détermine si le controle à le FrontContent en visuel
        /// </summary>
        public Boolean IsFrontInView
        {
            get
            {
                return (Boolean)GetValue(IsFrontInViewProperty);
            }
            set
            {
                SetValue(IsFrontInViewProperty, value);
            }
        }

Fonctions de calcul des rotations

    private double GetXRotation()
        {
            double rot = 0;
            switch (Direction)
            {
                case RotateDirection.BottomToTop:
                    rot = -180;
                    break;
                case RotateDirection.TopToBottom:
                    rot = 180;
                    break;
            }
            return rot;
        }
        private double GetYRotation()
        {
            double rot = 0;
            switch (Direction)
            {
                case RotateDirection.RightToLeft:
                    rot = 180;
                    break;
                case RotateDirection.LeftToRight:
                    rot = -180;
                    break;
            }
            return rot;
        }
        /// <summary>
        /// Effectue une rotation (uniquement si aucune action courrante n'est en cours)
        /// </summary>
        public void Rotate()
        {
            if (IsRotating == false)
            {
                GenerateAnimations();
                IsRotating = true;
                IsFrontInView = !IsFrontInView;
                switch (Direction)
                {
                    case RotateDirection.LeftToRight:
                    case RotateDirection.RightToLeft:
                        _animationY.Begin();
                        break;
                    case RotateDirection.BottomToTop:
                    case RotateDirection.TopToBottom:
                        _animationX.Begin();
                        break;
                }
            }
        }

Fonctions de génération des animations de rotation

     private void GenerateAnimations()
        {
            DoubleAnimation daY = null, daX = null;
            Boolean visibilityIncluded =false;
            #region Init / CleanUp Storyboard
            if (_animationY != null)
            {
                _animationY.Stop();
                _animationY.Children.Clear();
            }
            if (_animationX != null)
            {
                _animationX.Stop();
                _animationX.Children.Clear();
            }
            #endregion
            if (IsFrontInView)
            {
                _backContentPresenter.Visibility = Visibility.Collapsed;
                _frontContentPresenter.Visibility = Visibility.Visible;
            }
            else
            {
                _frontContentPresenter.Visibility = Visibility.Collapsed;
                _backContentPresenter.Visibility = Visibility.Visible;
            }
            #region Rotation
            if (GetYRotation() != 0) // détermine si on a besoin d'une rotation Y
            {
                daY = new DoubleAnimation()
                {
                    By = GetYRotation(),
                    Duration = new Duration(new TimeSpan(0, 0, 0, 0, (Int32)Duration)),
                    EasingFunction = new PowerEase()
                    {
                        Power = 5,
                        EasingMode = EasingMode.EaseInOut
                    }
                };
                Storyboard.SetTarget(daY, this);
                daY.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.Projection).(PlaneProjection.RotationY)"));
            }
            if (GetXRotation() != 0)// détermine si on a besoin d'une rotation X
            {
                daX = new DoubleAnimation()
              {
                  By = GetXRotation(),
                  Duration = new Duration(new TimeSpan(0, 0, 0, 0, (Int32)Duration)),
                  EasingFunction = new PowerEase()
                  {
                      Power = 5,
                      EasingMode = EasingMode.EaseInOut
                  }
              };
                Storyboard.SetTarget(daX, this);
                daX.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.Projection).(PlaneProjection.RotationX)"));
            }
            #endregion
            #region Visibility
            ObjectAnimationUsingKeyFrames kf = new ObjectAnimationUsingKeyFrames();
            ObjectAnimationUsingKeyFrames kf2 = new ObjectAnimationUsingKeyFrames();
            kf.KeyFrames.Add(new DiscreteObjectKeyFrame()
            {
                Value = Visibility.Collapsed,
                KeyTime = new TimeSpan(0, 0, 0, 0, ((Int32)Duration / 2))
            });
            kf2.KeyFrames.Add(new DiscreteObjectKeyFrame()
            {
                Value = Visibility.Visible,
                KeyTime = new TimeSpan(0, 0, 0, 0, ((Int32)Duration / 2))
            });
            Storyboard.SetTarget(kf, (IsFrontInView) ? (_frontContentPresenter) : (_backContentPresenter));
            kf.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.Visibility)"));
            Storyboard.SetTarget(kf2, (IsFrontInView) ? (_backContentPresenter) : (_frontContentPresenter));
            kf2.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.Visibility)"));
            #endregion
            #region Scaling
            DoubleAnimationUsingKeyFrames daScaleX = new DoubleAnimationUsingKeyFrames();
            daScaleX.KeyFrames.Add(new EasingDoubleKeyFrame()
            {
                Value = -1,
                KeyTime = new TimeSpan(0, 0, 0, 0, ((Int32)Duration / 2))
            });
            DoubleAnimationUsingKeyFrames daScaleY = new DoubleAnimationUsingKeyFrames();
            daScaleY.KeyFrames.Add(new EasingDoubleKeyFrame()
            {
                Value = -1,
                KeyTime = new TimeSpan(0, 0, 0, 0, ((Int32)Duration / 2))
            });
            Storyboard.SetTarget(daScaleX, (IsFrontInView) ? (_backContentPresenter) : (_frontContentPresenter));
            daScaleX.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.RenderTransform).(ScaleTransform.ScaleX)"));
            Storyboard.SetTarget(daScaleY, (IsFrontInView) ? (_backContentPresenter) : (_frontContentPresenter));
            daScaleY.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.RenderTransform).(ScaleTransform.ScaleY)"));
            #endregion
            if (daX != null)
            {
                visibilityIncluded = true;
                _animationX.Children.Add(kf);
                _animationX.Children.Add(kf2);
                _animationX.Children.Add(daScaleY);
                _animationX.Children.Add(daX);
            }
            if (daY != null)
            {
                if (!visibilityIncluded)
                {
                    _animationY.Children.Add(kf);
                    _animationY.Children.Add(kf2);
                }
                _animationY.Children.Add(daScaleX);
                _animationY.Children.Add(daY);
            }
        }

Code source complet

 /// <summary>
    /// Controle permettant d'afficher un controle caché via une animation de rotation
    /// </summary>
    public class ContentControl3D : Grid
    {
        #region Membres
        private Grid _rootLayout = new Grid();
        private ContentControl _frontContentPresenter = new ContentControl();
        private ContentControl _backContentPresenter = new ContentControl();
        private PlaneProjection _projection = null;
        private Storyboard _animationX = new Storyboard();
        private Storyboard _animationY = new Storyboard();
        /// <summary>
        /// Définit la DP représentant le contenu de la face principale
        /// </summary>
        private static readonly DependencyProperty FrontContentProperty =
            DependencyProperty.Register(
            "FrontContent",
            typeof(UIElement),
            typeof(ContentControl3D),
            new PropertyMetadata(null));
        /// <summary>
        /// Définit la DP représentant si le controle est en train de faire une rotation
        /// </summary>
        private static readonly DependencyProperty IsRotatingProperty =
           DependencyProperty.Register(
           "IsRotating",
           typeof(Boolean),
           typeof(ContentControl3D),
           new PropertyMetadata(null));
        /// <summary>
        /// Définit la DP définissant si le controle affiche le controle de la face principale
        /// </summary>
        private static readonly DependencyProperty IsFrontInViewProperty =
          DependencyProperty.Register(
          "IsFrontInView",
          typeof(Boolean),
          typeof(ContentControl3D),
          new PropertyMetadata(true));
        /// <summary>
        /// Définit la DP représentant le contenu de la face cachée
        /// </summary>
        private static readonly DependencyProperty BackContentProperty =
           DependencyProperty.Register(
           "BackContent",
           typeof(UIElement),
           typeof(ContentControl3D),
           new PropertyMetadata(null));
        /// <summary>
        /// Définit la DP représentant la durée de l'animation de rotation (en ms)
        /// </summary>
        private static readonly DependencyProperty DurationProperty =
           DependencyProperty.Register(
           "Duration",
           typeof(Double),
           typeof(ContentControl3D),
           new PropertyMetadata(600.0));
        /// <summary>
        /// Définit la DP représentant le sens de rotation du controle
        /// </summary>
        private static readonly DependencyProperty DirectionProperty =
           DependencyProperty.Register(
           "Direction",
           typeof(RotateDirection),
           typeof(ContentControl3D),
           new PropertyMetadata(null));
        #endregion
        #region Ctors
        /// <summary>
        /// Crée une instance du controle permettant d'afficher un controle caché via une animation de rotation
        /// </summary>
        public ContentControl3D()
        {
            Loaded += new RoutedEventHandler(OnLoaded);
            _animationX.Completed += new EventHandler(OnAnimationXCompleted);
            _animationY.Completed += new EventHandler(OnAnimationYCompleted);
        }
        #endregion
        #region Méthodes
        private void GenerateAnimations()
        {
            DoubleAnimation daY = null, daX = null;
            Boolean visibilityIncluded =false;
            #region Init / CleanUp Storyboard
            if (_animationY != null)
            {
                _animationY.Stop();
                _animationY.Children.Clear();
            }
            if (_animationX != null)
            {
                _animationX.Stop();
                _animationX.Children.Clear();
            }
            #endregion
            if (IsFrontInView)
            {
                _backContentPresenter.Visibility = Visibility.Collapsed;
                _frontContentPresenter.Visibility = Visibility.Visible;
            }
            else
            {
                _frontContentPresenter.Visibility = Visibility.Collapsed;
                _backContentPresenter.Visibility = Visibility.Visible;
            }
            #region Rotation
            if (GetYRotation() != 0) // détermine si on a besoin d'une rotation Y
            {
                daY = new DoubleAnimation()
                {
                    By = GetYRotation(),
                    Duration = new Duration(new TimeSpan(0, 0, 0, 0, (Int32)Duration)),
                    EasingFunction = new PowerEase()
                    {
                        Power = 5,
                        EasingMode = EasingMode.EaseInOut
                    }
                };
                Storyboard.SetTarget(daY, this);
                daY.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.Projection).(PlaneProjection.RotationY)"));
            }
            if (GetXRotation() != 0)// détermine si on a besoin d'une rotation X
            {
                daX = new DoubleAnimation()
              {
                  By = GetXRotation(),
                  Duration = new Duration(new TimeSpan(0, 0, 0, 0, (Int32)Duration)),
                  EasingFunction = new PowerEase()
                  {
                      Power = 5,
                      EasingMode = EasingMode.EaseInOut
                  }
              };
                Storyboard.SetTarget(daX, this);
                daX.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.Projection).(PlaneProjection.RotationX)"));
            }
            #endregion
            #region Visibility
            ObjectAnimationUsingKeyFrames kf = new ObjectAnimationUsingKeyFrames();
            ObjectAnimationUsingKeyFrames kf2 = new ObjectAnimationUsingKeyFrames();
            kf.KeyFrames.Add(new DiscreteObjectKeyFrame()
            {
                Value = Visibility.Collapsed,
                KeyTime = new TimeSpan(0, 0, 0, 0, ((Int32)Duration / 2))
            });
            kf2.KeyFrames.Add(new DiscreteObjectKeyFrame()
            {
                Value = Visibility.Visible,
                KeyTime = new TimeSpan(0, 0, 0, 0, ((Int32)Duration / 2))
            });
            Storyboard.SetTarget(kf, (IsFrontInView) ? (_frontContentPresenter) : (_backContentPresenter));
            kf.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.Visibility)"));
            Storyboard.SetTarget(kf2, (IsFrontInView) ? (_backContentPresenter) : (_frontContentPresenter));
            kf2.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.Visibility)"));
            #endregion
            #region Scaling
            DoubleAnimationUsingKeyFrames daScaleX = new DoubleAnimationUsingKeyFrames();
            daScaleX.KeyFrames.Add(new EasingDoubleKeyFrame()
            {
                Value = -1,
                KeyTime = new TimeSpan(0, 0, 0, 0, ((Int32)Duration / 2))
            });
            DoubleAnimationUsingKeyFrames daScaleY = new DoubleAnimationUsingKeyFrames();
            daScaleY.KeyFrames.Add(new EasingDoubleKeyFrame()
            {
                Value = -1,
                KeyTime = new TimeSpan(0, 0, 0, 0, ((Int32)Duration / 2))
            });
            Storyboard.SetTarget(daScaleX, (IsFrontInView) ? (_backContentPresenter) : (_frontContentPresenter));
            daScaleX.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.RenderTransform).(ScaleTransform.ScaleX)"));
            Storyboard.SetTarget(daScaleY, (IsFrontInView) ? (_backContentPresenter) : (_frontContentPresenter));
            daScaleY.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.RenderTransform).(ScaleTransform.ScaleY)"));
            #endregion
            if (daX != null)
            {
                visibilityIncluded = true;
                _animationX.Children.Add(kf);
                _animationX.Children.Add(kf2);
                _animationX.Children.Add(daScaleY);
                _animationX.Children.Add(daX);
            }
            if (daY != null)
            {
                if (!visibilityIncluded)
                {
                    _animationY.Children.Add(kf);
                    _animationY.Children.Add(kf2);
                }
                _animationY.Children.Add(daScaleX);
                _animationY.Children.Add(daY);
            }
        }
        private double GetXRotation()
        {
            double rot = 0;
            switch (Direction)
            {
                case RotateDirection.BottomToTop:
                    rot = -180;
                    break;
                case RotateDirection.TopToBottom:
                    rot = 180;
                    break;
            }
            return rot;
        }
        private double GetYRotation()
        {
            double rot = 0;
            switch (Direction)
            {
                case RotateDirection.RightToLeft:
                    rot = 180;
                    break;
                case RotateDirection.LeftToRight:
                    rot = -180;
                    break;
            }
            return rot;
        }
        /// <summary>
        /// Effectue une rotation (uniquement si aucune action courrante n'est en cours)
        /// </summary>
        public void Rotate()
        {
            if (IsRotating == false)
            {
                GenerateAnimations();
                IsRotating = true;
                IsFrontInView = !IsFrontInView;
                switch (Direction)
                {
                    case RotateDirection.LeftToRight:
                    case RotateDirection.RightToLeft:
                        _animationY.Begin();
                        break;
                    case RotateDirection.BottomToTop:
                    case RotateDirection.TopToBottom:
                        _animationX.Begin();
                        break;
                }
            }
        }
        #endregion
        #region Handlers
        void OnLoaded(object sender, RoutedEventArgs e)
        {
            Loaded -= OnLoaded;
            _frontContentPresenter.RenderTransformOrigin = new Point(0.5, 0.5);
            _frontContentPresenter.RenderTransform = new ScaleTransform();
            _frontContentPresenter.HorizontalContentAlignment = HorizontalAlignment.Stretch;
            _frontContentPresenter.VerticalContentAlignment = VerticalAlignment.Stretch;
            _backContentPresenter.RenderTransformOrigin = new Point(0.5, 0.5);
            _backContentPresenter.RenderTransform = new ScaleTransform();
            _backContentPresenter.HorizontalContentAlignment = HorizontalAlignment.Stretch;
            _backContentPresenter.VerticalContentAlignment = VerticalAlignment.Stretch;
            _backContentPresenter.Visibility = Visibility.Collapsed;
            _projection = new PlaneProjection();
            Projection = _projection;
            Children.Add(_backContentPresenter);
            Children.Add(_frontContentPresenter);
            Children.Add(_rootLayout);
            _frontContentPresenter.Visibility = Visibility.Visible;
            _backContentPresenter.Visibility = Visibility.Collapsed;
            _backContentPresenter.Content = BackContent;
            _frontContentPresenter.Content = FrontContent;
        }
        void OnAnimationYCompleted(object sender, EventArgs e)
        {
            Storyboard s = sender as Storyboard;
            if (s != null)
            {
                s.Completed -= OnAnimationXCompleted;
            }
            IsRotating = false;
        }
        void OnAnimationXCompleted(object sender, EventArgs e)
        {
            Storyboard s = sender as Storyboard;
            if (s != null)
            {
                s.Completed -= OnAnimationYCompleted;
            }
            IsRotating = false;
        }
        #endregion
        #region DP
        /// <summary>
        /// Obtient ou définit le ContentPresenter associé à la face principale
        /// </summary>
        public UIElement FrontContent
        {
            get
            {
                return (UIElement)GetValue(FrontContentProperty);
            }
            set
            {
                SetValue(FrontContentProperty, value);
            }
        }
        /// <summary>
        /// Obtient ou définit le ContentPresenter associé à la face cachée
        /// </summary>
        public UIElement BackContent
        {
            get
            {
                return (UIElement)GetValue(BackContentProperty);
            }
            set
            {
                SetValue(BackContentProperty, value);
            }
        }
        /// <summary>
        /// Obtient ou définit le sens de rotation du controle
        /// </summary>
        public RotateDirection Direction
        {
            get
            {
                return (RotateDirection)GetValue(DirectionProperty);
            }
            set
            {
                SetValue(DirectionProperty, value);
            }
        }
        /// <summary>
        /// Obtient ou définit si le controle est en train d'effectuer une rotation
        /// </summary>
        public Boolean IsRotating
        {
            get
            {
                return (Boolean)GetValue(IsRotatingProperty);
            }
            set
            {
                SetValue(IsRotatingProperty, value);
            }
        }
        /// <summary>
        /// Obtient ou définit la durée de l'animation de rotation
        /// </summary>
        public Double Duration
        {
            get
            {
                return (Double)GetValue(DurationProperty);
            }
            set
            {
                SetValue(DurationProperty, value);
            }
        }
        /// <summary>
        /// Détermine si le controle à le FrontContent en visuel
        /// </summary>
        public Boolean IsFrontInView
        {
            get
            {
                return (Boolean)GetValue(IsFrontInViewProperty);
            }
            set
            {
                SetValue(IsFrontInViewProperty, value);
            }
        }
        #endregion
    }

Exemple d’utilisation coté XAML

<controls:ContentControl3D x:Name="Rotator"
    			Width="300"
    			Height="300"
    			Background="Gray"
    			Direction="{Binding SelectedItem, ElementName=comboBox, Mode=OneWay}"
                                   d:LayoutOverrides="GridBox">
    			<controls:ContentControl3D.FrontContent>
    				<!-- face avant -->
    			</controls:ContentControl3D.FrontContent>
    			<controls:ContentControl3D.BackContent>
    				<!-- face arrière -->
    			</controls:ContentControl3D.BackContent>
    		</controls:ContentControl3D>

Réalisation d’une application d’exemple

Code XAML

<UserControl
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:controls="clr-namespace:SL3DContentControl" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" x:Class="SL3DContentControl.MainPage"
             mc:Ignorable="d">
    <Grid x:Name="LayoutRoot"
          Background="#FFE0E0E0">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Border Margin="5"
                VerticalAlignment="Top"
                Background="White">
            <Border.Effect>
                <DropShadowEffect ShadowDepth="0"
                                  Opacity="0.8" />
            </Border.Effect>
            <StackPanel Height="104"
                        Margin="5">
                <TextBlock Text="Direction"
                           TextWrapping="Wrap"
                           FontWeight="Bold" />
                <ComboBox x:Name="comboBox"
                          Width="300"
                          SelectedIndex="0"
                          HorizontalAlignment="Left"
                          Margin="0,3,0,0">
                    <controls:RotateDirection>LeftToRight</controls:RotateDirection>
                    <controls:RotateDirection>RightToLeft</controls:RotateDirection>
                    <controls:RotateDirection>TopToBottom</controls:RotateDirection>
                    <controls:RotateDirection>BottomToTop</controls:RotateDirection>
                </ComboBox>
                <TextBlock Text="Durée"
                           TextWrapping="Wrap"
                           FontWeight="Bold"
                           Margin="0,3,0,0" />
                <Slider Minimum="300"
                        Maximum="3000"
                        Value="{Binding Duration, ElementName=Rotator, Mode=TwoWay}"
                        Width="300"
                        HorizontalAlignment="Left"
                        Margin="0,3,0,0" />
                <Button HorizontalAlignment="Left"
                        Margin="0,3,0,0"
                        Content="Rotation !"
                        Click="Button_Click" />
            </StackPanel>
        </Border>
        <Border Margin="5"
                Grid.Row="1">
        	<Border.Background>
        		<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
        			<GradientStop Color="#FFEAEAEA" Offset="0"/>
        			<GradientStop Color="#FF8E8E8E" Offset="1"/>
        		</LinearGradientBrush>
        	</Border.Background>
            <Border.Effect>
                <DropShadowEffect ShadowDepth="0"
                                  Opacity="0.8" />
            </Border.Effect>
        </Border>
    	<Grid Grid.Row="1" Margin="10" HorizontalAlignment="Center" VerticalAlignment="Center">
    		<controls:ContentControl3D x:Name="Rotator"
    			Width="300"
    			Height="300"
    			Background="Gray"
    			Direction="{Binding SelectedItem, ElementName=comboBox, Mode=OneWay}"
                                   d:LayoutOverrides="GridBox">
    			<controls:ContentControl3D.FrontContent>
    				<Grid>
    					<Border Background="White">
    						<Image Source="microsoft_silverlight_c.jpg"
    							Stretch="Uniform"
    							VerticalAlignment="Center"
    							HorizontalAlignment="Center"
    							Margin="5" />
    					</Border>
    					<Button Content="Detail"
    						Margin="0,0,5,5"
    						Click="Button_Click"
    						HorizontalAlignment="Right"
    						VerticalAlignment="Bottom" />
    				</Grid>
    			</controls:ContentControl3D.FrontContent>
    			<controls:ContentControl3D.BackContent>
    				<Border Background="White">
    					<Grid Margin="5">
    						<Grid.RowDefinitions>
    							<RowDefinition />
    							<RowDefinition Height="Auto" />
    						</Grid.RowDefinitions>
    						<TextBlock Text="Silverlight est une technologie permettant de développer et d'exécuter des Applications Internet Riches (RIA) dans les principaux navigateurs web disponibles aujourd'hui. Un des apports fondamentaux de la version 2 est la possibilité de tirer partie du .NET Framework."
    							VerticalAlignment="Top"
    							TextWrapping="Wrap"
    							ScrollViewer.VerticalScrollBarVisibility="Auto" />
    						<HyperlinkButton HorizontalAlignment="Right"
    							VerticalAlignment="Bottom"
    							Content="Silverlight"
    							Grid.Row="1"
    							NavigateUri="http://silverlight.net/"
    							TargetName="_blank" />
    						<Button Content="&amp;lt;- Retour"
    							Margin="5,5,0,0"
    							Click="Button_Click"
    							Grid.Row="1"
    							HorizontalAlignment="Left"
    							VerticalAlignment="Bottom" />
    					</Grid>
    				</Border>
    			</controls:ContentControl3D.BackContent>
    		</controls:ContentControl3D>
    	</Grid>
    </Grid>
</UserControl>

Code Behind

using System.Windows;
using System.Windows.Controls;
namespace SL3DContentControl
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Rotator.Rotate();
        }
    }
}

Voilà à présent vous disposez d’un moyent élégant d’afficher un cotrole caché via une animation de rotation 🙂
Code source complet + application d’exemple SL3DContentControl.zip

Publicités
Catégories :Silverlight, Silverlight 3