2010-08-03 7 views
4

Je voudrais avoir la largeur d'un article rétrécir sur un clic d'un bouton.Shrink Panel dans Silverlight Storyboard

À l'heure actuelle, j'ai deux objets essentiellement, lorsque vous cliquez sur le bouton sur l'objet A, un story-board démarre qui le fait pivoter autour de l'axe des x et le réduit. Ensuite, il montre objectB en définissant sa visibilité visible et le fait pivoter en vue. Tout ce que je veux ajouter, c'est de réduire la largeur lorsque le storyboard arrive à objectA et à objectB, puis de revenir à la normale à la fin du storyboard.

J'ai essayé de définir l'épaisseur, mais j'ai reçu une erreur de compilation se plaignant qu'elle était en lecture seule.

<ObjectAnimationUsingKeyFrames 
      BeginTime="00:00:00" 
      Storyboard.TargetName="objectA" 
      Storyboard.TargetProperty="(UIElement.Margin)"> 
     <DiscreteObjectKeyFrame KeyTime="00:00:00"> 
     <DiscreteObjectKeyFrame.Value> 
      <Thickness Left="10" Right="10"/> 
     </DiscreteObjectKeyFrame.Value> 
     </DiscreteObjectKeyFrame> 
    </ObjectAnimationUsingKeyFrames> 

J'ai une simple mise en page pour le moment ...

Voici mon XAML UI:

<StackPanel> 
    <Border x:Name="objectA" BorderBrush="Blue" BorderThickness="1" Height="100" Width="100"> 
     <StackPanel> 
     <TextBox Margin="10"></TextBox> 
     <Button Width="50" x:Name="btn1" Content="Flip" Click="btn1_Click"/> 
     </StackPanel> 
    <Border.Projection> 
     <PlaneProjection RotationX="0"></PlaneProjection> 
    </Border.Projection> 
    </Border> 

    <Border Visibility="Collapsed" x:Name="objectB" BorderBrush="Red" BorderThickness="1" Height="100" Width="100"> 
    <StackPanel> 
     <TextBox Margin="10"></TextBox> 
     <Button Width="50" x:Name="btn2" Content="Flip" Click="btn2_Click"/> 
    </StackPanel> 
    <Border.Projection> 
     <PlaneProjection RotationX="90"></PlaneProjection> 
    </Border.Projection> 
    </Border> 

Voici le story-board ...

<Storyboard x:Name="Storyboardtest"> 
      <DoubleAnimation BeginTime="00:00:00" 
       Storyboard.TargetName="objectA" 
       Storyboard.TargetProperty="(UIElement.Projection).(RotationX)" 

       From="0" To="-90"> 
      </DoubleAnimation> 
      <ObjectAnimationUsingKeyFrames 
       BeginTime="00:00:01" 
       Storyboard.TargetName="objectA" 
       Storyboard.TargetProperty="(UIElement.Visibility)"> 

       <DiscreteObjectKeyFrame KeyTime="00:00:00"> 
        <DiscreteObjectKeyFrame.Value> 
         <Visibility>Collapsed</Visibility> 
        </DiscreteObjectKeyFrame.Value> 
       </DiscreteObjectKeyFrame> 

      </ObjectAnimationUsingKeyFrames> 

      <ObjectAnimationUsingKeyFrames 
       BeginTime="00:00:01" 
       Storyboard.TargetName="objectB" 
       Storyboard.TargetProperty="(UIElement.Visibility)"> 

       <DiscreteObjectKeyFrame KeyTime="00:00:00"> 
        <DiscreteObjectKeyFrame.Value> 
         <Visibility>Visible</Visibility> 
        </DiscreteObjectKeyFrame.Value> 
       </DiscreteObjectKeyFrame> 

      </ObjectAnimationUsingKeyFrames> 

      <DoubleAnimation BeginTime="00:00:01" 
       Storyboard.TargetName="objectB" 
       Storyboard.TargetProperty="(UIElement.Projection).(RotationX)" 

       From="90" To="0"> 
      </DoubleAnimation> 

     </Storyboard> 
+0

Désolé, voulez-vous changer la taille réelle de la commande ou simplement réduire la largeur de contrôle visuellement (par exemple en utilisant la mise à l'échelle)? Merci. –

Répondre

5

Si c'est juste la visu al largeur que vous souhaitez affecter, ajoutez ce qui suit à votre storyboard. Il donnera l'apparence des contrôles mobiles dans la distance et le dos comme flips:

<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Storyboard.TargetName="objectA"> 
     <EasingDoubleKeyFrame KeyTime="0" Value="1"/> 
     <EasingDoubleKeyFrame KeyTime="0:0:1" Value="0.5"/> 
    </DoubleAnimationUsingKeyFrames> 
    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Storyboard.TargetName="objectB"> 
     <EasingDoubleKeyFrame KeyTime="0" Value="1"/> 
     <EasingDoubleKeyFrame KeyTime="0:0:1" Value="0.5"/> 
     <EasingDoubleKeyFrame KeyTime="0:0:2" Value="1"/> 
    </DoubleAnimationUsingKeyFrames> 

vous devez également ajouter ce qui suit comme je mélange d'expression pour ajouter l'animation et il ajoute automatiquement les éléments requis:

<Border x:Name="objectA" BorderBrush="Blue" BorderThickness="1" Height="100" Width="100" RenderTransformOrigin="0.5,0.5"> 
     <Border.RenderTransform> 
      <CompositeTransform/> 
     </Border.RenderTransform> 

[Snip]

<Border Visibility="Collapsed" x:Name="objectB" BorderBrush="Red" BorderThickness="1" Height="100" Width="100" RenderTransformOrigin="0.5,0.5"> 
     <Border.RenderTransform> 
      <CompositeTransform/> 
     </Border.RenderTransform> 
+0

Je reçois cette erreur lorsque je dépose votre code dans mon exemple. 'Impossible de résoudre TargetProperty (UIElement.RenderTransform). (CompositeTransform.ScaleX) sur l'objet spécifié. ' – Gabe

+0

Vous remarquerez dans les extraits XAML manquants que j'ai ajouté qu'il a RenderTransformOrigin =" 0.5,0.5 "sur les 2 bordures.Cela signifie que la mise à l'échelle aura lieu sur le centre et non sur les valeurs par défaut. Désolé, j'ai omis certains détails. –

+0

Très gentil, merci gentil monsieur. – Gabe

0

le problème est que les deux propriétés Largeur et la marge ne sont pas DependencyProperties donc ils ne peuvent pas être animés. Pour contourner cette difficulté, vous devez ajouter certaines DependencyProperties personnalisées à votre code de contrôle utilisateur, qui peut être connecté au storyboard et peut à son tour manipuler les propriétés réelles des objets.

Par exemple, vous pouvez ajouter cette DependencyProperty à votre UserControl qui permettent essentiellement la définition de la propriété Largeur de l'objet A:

public static readonly DependencyProperty ObjectWidthProperty = DependencyProperty.Register(
    "ObjectWidth", 
    typeof(double), 
    typeof(MainPage), 
    new PropertyMetadata(50.0, new PropertyChangedCallback(OnObjectWidthChanged))); 

public double ObjectWidth 
{ 
    get { return (double)GetValue(ObjectWidthProperty); } 
    set { SetValue(ObjectWidthProperty, value); } 
} 

private static void OnObjectWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    ((MainPage)d).OnObjectWidthChanged(e); 
} 

private void OnObjectWidthChanged(DependencyPropertyChangedEventArgs e) 
{ 
    this.objectA.Width = this.ObjectWidth; 
} 

Vous pouvez ensuite ajouter ce qui suit à votre story-board qui animerait la largeur de objectA de 50 pixels vers le bas à 0:

<DoubleAnimation BeginTime="00:00:00" 
       Storyboard.TargetName="MyControl" 
       Storyboard.TargetProperty="ObjectWidth" 
       From="50" To="0"/> 

Le serait également vous obliger à ajouter x: Name = "MyControl" à votre UserControl haut niveau. C'est un peu hacky, mais cela fonctionne pour animer certaines des propriétés sous-jacentes des éléments qui ne sont pas DependencyPropertys.

+0

Bien que cela fonctionne je ne veux pas rétrécir tout le contrôle de l'utilisateur ... Mais peut-être que je peux l'utiliser comme point de départ :) – Gabe

+0

Cela ne réduit pas réellement le contrôle de l'utilisateur entier, juste objectA. DependencyProperty est simplement exposé sur le contrôle utilisateur pour manipuler la largeur de objectA car un storyboard ne peut pas modifier directement la propriété Width de objectA. –