2010-06-14 20 views
2

J'ai un UserControl qui est une classe de base pour les autres contrôles utilisateur, qui sont affichés dans une "vue modale".
Je souhaite que toutes les commandes utilisateur s'affichent lorsqu'elles sont affichées et qu'elles disparaissent une fois fermées. Je veux aussi que l'utilisateur puisse déplacer les contrôles. Mon constructeur ressemble à ceci:Comportement d'interaction de fusion donne l'erreur "points à l'instance immutable"

var tg = new TransformGroup(); 
tg.Children.Add(new ScaleTransform()); 
RenderTransform = tg; 
var behaviors = Interaction.GetBehaviors(this); 
behaviors.Add(new TranslateZoomRotateBehavior()); 

Loaded += ModalDialogBase_Loaded; 

Et la méthode ModalDialogBase_Loaded ressemble à ceci:

private void ModalDialogBase_Loaded(object sender, RoutedEventArgs e) 
{ 
    var fadeInStoryboard = (Storyboard)TryFindResource("modalDialogFadeIn"); 
    fadeInStoryboard.Begin(this); 
} 

Lorsque j'appuie sur un gros bouton sur le contrôle de cette méthode est appelée:

protected virtual void Close() 
{ 
    var fadeOutStoryboard = (Storyboard)TryFindResource("modalDialogFadeOut"); 
    fadeOutStoryboard = fadeOutStoryboard.Clone(); 
    fadeOutStoryboard.Completed += delegate 
    { 
     RaiseEvent(new RoutedEventArgs(ClosedEvent)); 
    }; 
    fadeOutStoryboard.Begin(this); 
} 

Le story-board pour disparaître ressemble à ceci:

<Storyboard x:Key="modalDialogFadeOut"> 
    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="{x:Null}"> 
     <EasingDoubleKeyFrame KeyTime="0" Value="1"> 
      <EasingDoubleKeyFrame.EasingFunction> 
       <BackEase EasingMode="EaseIn" Amplitude="0.3" /> 
      </EasingDoubleKeyFrame.EasingFunction> 
     </EasingDoubleKeyFrame> 
     <EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="0"> 
      <EasingDoubleKeyFrame.EasingFunction> 
       <BackEase EasingMode="EaseIn" Amplitude="0.3" /> 
      </EasingDoubleKeyFrame.EasingFunction> 
     </EasingDoubleKeyFrame> 
    </DoubleAnimationUsingKeyFrames> 
    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" Storyboard.TargetName="{x:Null}"> 
     <EasingDoubleKeyFrame KeyTime="0" Value="1"> 
      <EasingDoubleKeyFrame.EasingFunction> 
       <BackEase EasingMode="EaseIn" Amplitude="0.3" /> 
      </EasingDoubleKeyFrame.EasingFunction> 
     </EasingDoubleKeyFrame> 
     <EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="0"> 
      <EasingDoubleKeyFrame.EasingFunction> 
       <BackEase EasingMode="EaseIn" Amplitude="0.3" /> 
      </EasingDoubleKeyFrame.EasingFunction> 
     </EasingDoubleKeyFrame> 
    </DoubleAnimationUsingKeyFrames> 
    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="{x:Null}"> 
     <EasingDoubleKeyFrame KeyTime="0" Value="1" /> 
     <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0" /> 
     <EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="0" /> 
    </DoubleAnimationUsingKeyFrames> 
</Storyboard> 

Si le contrôle utilisateur est affiché et que l'utilisateur ne le déplace PAS sur l'écran, tout fonctionne correctement. Cependant, si l'utilisateur déplace le contrôle, j'obtiens l'erreur suivante lorsque le storyboard modalDialogFadeOut est démarré:

Valeur de la propriété enfant dans le chemin '(0). (1) [0]. (2) 'indique une instance immuable de' System.Windows.Media.TransformCollection '.

Comment puis-je résoudre ce problème?

Répondre

4

Le problème est que TranslateZoomRotateBehavior remplace votre ScaleTransform par un MatrixTransform, provoquant les deux premières animations de votre Storyboard à cibler une propriété qui n'existe plus.

Puisque vous ne pouvez pas animer les valeurs d'une matrice pour obtenir l'effet de fondu, j'utiliserais un contrôle de conteneur supplémentaire. Le plus extérieur pour le comportement, puis un intérieur pour disparaître visuellement.

+0

Fantastique! Juste ce que je cherchais - merci! – kennethkryger