2010-03-24 10 views
1

Dans le gestionnaire de l'événement Completed d'un Storyboard, comment obtenir l'élément auquel le storyboard a été appliqué?Manipulation de l'objet cible d'un storyboard

Mon Storyboard fait partie d'un ItemTemplate:

<ListBox x:Name="MyListBox" > 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <Grid x:Name="Container" Height="30" > 
       <Grid.Resources> 
        <Storyboard x:Name="FadeOut" BeginTime="0:0:7" Completed="FadeOut_Completed"> 
         <DoubleAnimation From="1.0" To="0.0" Duration="0:0:3" Storyboard.TargetName="Container" Storyboard.TargetProperty="Opacity" /> 
        </Storyboard> 
       </Grid.Resources> 

       [...snip...] 

      </Grid> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

en cas Completed je veux saisir la grille appelée Container afin que je puisse faire des choses désagréables avec son DataContext. Est-ce que cela peut être fait ou est-ce que je vais dans le mauvais sens?

Merci :)

Répondre

2

La réponse est qu'il est impossible - pas Silverlight 3 de toute façon. En utilisant un débogueur, j'ai été capable de trouver une propriété privée du Storyboard que lorsque je l'ai remonté dans l'arborescence d'objets je suis arrivé à l'élément de template contenant - mais je ne pouvais pas le toucher du code en utilisant la réflexion due à la sécurité restrictions imposées aux applications Silverlight (cela peut être possible dans WPF si).

Ma solution éventuelle impliquait l'utilisation d'un Dictionary<Storyboard, Grid> et de deux gestionnaires d'événements. Avec le modèle auquel j'ai joint un gestionnaire Loaded, cela signifie que mon gestionnaire est appelé chaque fois qu'une instance du modèle est créée et chargée (c'est-à-dire pour chaque élément de données lié à la liste). À ce stade, j'ai une référence à l'instance physique du modèle, donc je peux chercher ses enfants pour le story-board:

private void ItemTemplate_Loaded(object sender, RoutedEventArgs e) 
{ 
    Storyboard s = getStoryBoard(sender); 
    if (s != null) 
    { 
     if (!_startedStoryboards.ContainsKey(s)) 
      _startedStoryboards.Add(s, (Grid)sender); 
    } 
} 

private Storyboard getStoryBoard(object container) 
{ 
    Grid g = container as Grid; 
    if (g != null) 
    { 
     if (g.Resources.Contains("FadeOut")) 
     { 
      Storyboard s = g.Resources["FadeOut"] as Storyboard; 
      return s; 
     } 
    } 
    return null; 
} 

private Dictionary<Storyboard, Grid> _startedStoryboards = new Dictionary<Storyboard, Grid>(); 

Puis lorsque l'événement Completed du story-board est tiré, je peux facilement utiliser ce dictionnaire comme recherche pour récupérer le modèle d'élément il a été hébergé au sein et à partir de là je peux obtenir le DataContext du modèle de l'article et faire les choses désagréables i prévu:

private void FadeOut_Completed(object sender, EventArgs e) 
{ 
    if (_startedStoryboards.ContainsKey((Storyboard)sender)) 
    { 
     Grid g = _startedStoryboards[(Storyboard)sender]; 
     if (g.DataContext != null) 
     { 
      MyDataItem z = g.DataContext as MyDataItem; 

      if (z != null) 
      { 
       ... do my thing ... 
      } 
     } 
    } 
} 

[note: ce code a été aseptisés pour le visionnement public , excusez les petites divergences ou erreurs syntaxiques que vous pourriez déceler]