2016-06-22 4 views
1

In meiner Chat-Anwendung habe ich eine Liste von Benutzern, in denen wer eine Nachricht sendet und wenn sein Chat-Fenster nicht auf der Benutzerseite geöffnet ist, dann blinkt sein Name in der Listbox, um Benutzer über eingehende Nachrichten zu benachrichtigen. Ich entferne die Animation, wenn der Benutzer diesen Absender auswählt. Aber die Animation stoppt nur für das Element, auf das die Animation zuletzt angewendet wurde.Wie stoppe Storyboard Animation auf ListBoxItem?

Unten ist der Code, den ich für die Anwendung Animation ListBoxItem verwenden,

private void BlinkSenderUsername(int index, string userRole) 
    { 
     blinkAnimation = new DoubleAnimationUsingKeyFrames(); 
     blinkAnimation.KeyFrames.Add(new DiscreteDoubleKeyFrame(1, KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(0)))); 
     blinkAnimation.KeyFrames.Add(new DiscreteDoubleKeyFrame(0, KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(250)))); 
     ListBoxItem target = new ListBoxItem(); 

    target = OnlineUserList.ItemContainerGenerator.ContainerFromIndex(index) as ListBoxItem; 
     OnlineUserList.ScrollIntoView(target); 

     blinkStoryboard = new Storyboard 
     { 
      Duration = TimeSpan.FromMilliseconds(900), 
      RepeatBehavior = RepeatBehavior.Forever, 
     }; 

     Storyboard.SetTarget(blinkAnimation, target); 
     Storyboard.SetTargetProperty(blinkAnimation, new PropertyPath(OpacityProperty)); 

     blinkStoryboard.Children.Add(blinkAnimation); 
     blinkStoryboard.Begin(target, true); 
    } 

und auf Auswahlereignis von Listbox geändert (Animation auf der Auswahl zu stoppen):

private void OnlineUserListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
    ListBoxItem listBoxItem = OnlineUserList.ItemContainerGenerator.ContainerFromItem(OnlineUserList.SelectedItem) as ListBoxItem; 
       if (listBoxItem != null && listBoxItem.HasAnimatedProperties) 
       { 
        blinkStoryboard.Stop(listBoxItem); 
       } 

}

Kann mir jemand vorschlagen, was mache ich falsch?

EDIT (nach Jai Antwort): -

static void MyClassStaticConstructor() 
    { 
     BlinkAnimation = new DoubleAnimationUsingKeyFrames(); 
     BlinkAnimation.KeyFrames.Add(new DiscreteDoubleKeyFrame(1, KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(0)))); 
     BlinkAnimation.KeyFrames.Add(new DiscreteDoubleKeyFrame(0, KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(250)))); 

     BlinkStoryboard = new Storyboard 
     { 
      Duration = TimeSpan.FromMilliseconds(900), 
      RepeatBehavior = RepeatBehavior.Forever, 
     }; 

     BlinkStoryboard.Children.Add(BlinkAnimation); 
    } 

    private void BlinkSenderUsername(int index, string userRole) 
    { 
     // There is no need to instantiate a ListBoxItem 
     //ListBoxItem target = new ListBoxItem(); 
      ListBoxItem target = OnlineUserList.ItemContainerGenerator.ContainerFromIndex(index) as ListBoxItem; 

     if (target == null) return; 
     MyClassStaticConstructor(); 
     Storyboard.SetTarget(BlinkAnimation, target); 
     Storyboard.SetTargetProperty(BlinkAnimation, new PropertyPath(OpacityProperty)); 

     BlinkStoryboard.Begin(target, true); 
    } 

und in selection Falle listbox:

private void OnlineUserListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
ListBoxItem listBoxItem = OnlineUserList.ItemContainerGenerator.ContainerFromItem(OnlineUserList.SelectedItem) as ListBoxItem; 
      if (listBoxItem != null && listBoxItem.HasAnimatedProperties) 
      { 
       BlinkStoryboard.Stop(listBoxItem); 
      }} 
+0

Was bedeutet "Aber animation stoppt für alle anderen listboxitems außer dem Element, auf das die Animation zuerst angewendet wurde." meint? – Jai

+0

Ich bin in der Lage, die Animation für alle anderen Sender bei der Auswahl zu stoppen, aber mit Ausnahme des Sendernamens, auf den die Animation das erste Mal angewendet wurde (dh der Benutzer erhält eine Nachricht von UserA, dann blinkt sein Name und der Benutzer erhält eine Nachricht von UserB) beginnt zu blinken), wenn ich auf UserB klicke, stoppt die Animation, aber wenn ich auf UserA klicke, blinkt sie weiter. Ist es jetzt klar? – NewbieCoder

+0

Debug-Code erneut und erkannte, dass die Animation nur für das Element stoppt, auf das sie zuletzt angewendet wurde. – NewbieCoder

Antwort

1

Das Problem ist, dass für jede ListBoxItem, erstellen Sie eine Storyboard und ein Animation Objekt. Sowohl das Storyboard als auch die Animationsobjekte werden in einem einzigen globalen Feld gespeichert. Wenn Sie mehrere solcher Animationen festlegen, haben Ihre globalen Felder die Referenzen nur die Animation/Storyboard, die zuletzt hinzugefügt wurden.

Ändern Sie die Implementierung dieser:

private static readonly DoubleAnimationUsingKeyFrames BlinkAnimation; 
private static readonly Storyboard BlinkStoryboard; 

static MyClassStaticConstructor() 
{ 
    BlinkAnimation = new DoubleAnimationUsingKeyFrames(); 
    BlinkAnimation.KeyFrames.Add(new DiscreteDoubleKeyFrame(1, KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(0)))); 
    BlinkAnimation.KeyFrames.Add(new DiscreteDoubleKeyFrame(0, KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(250)))); 

    BlinkStoryboard = new Storyboard 
    { 
     Duration = TimeSpan.FromMilliseconds(900), 
     RepeatBehavior = RepeatBehavior.Forever, 
    }; 

    BlinkStoryboard.Children.Add(blinkAnimation); 
} 

private void BlinkSenderUsername(int index, string userRole) 
{ 
    // There is no need to instantiate a ListBoxItem 
    //ListBoxItem target = new ListBoxItem(); 
    ListBoxItem target = OnlineUserList.ItemContainerGenerator.ContainerFromIndex(index) as ListBoxItem; 

    if (target == null) return; // Just make sure we managed to get a ListBoxItem instance 
    OnlineUserList.ScrollIntoView(target); 

    Storyboard.SetTarget(BlinkAnimation, target); 
    Storyboard.SetTargetProperty(BlinkAnimation, new PropertyPath(OpacityProperty)); 

    BlinkStoryboard.Begin(target, true); 
} 

Animationen und Storyboards Objekte sind wieder verwendbar - also, wenn mehrere Steuerelemente die gleiche Animation benötigen, können sie die gleiche Animation/Storyboard-Instanzen verwenden. Sie müssen es nur einmal instanziieren. In meiner Antwort habe ich sie statisch gemacht, aber Sie haben die Wahl, sie nicht statisch zu machen.

+0

Ich hatte Null Referenz Ausnahme so genannte MyClassStaticConstructor() direkt über Storyboard.SetTarget (BlinkAnimation, Ziel); Aber das Problem ist immer noch das gleiche; Animation stoppt nur für den letzten Artikel – NewbieCoder

+0

Vielen Dank für die Lösung Jai. Es funktioniert endlich so, wie ich es wollte. Du hast meinen Tag gerettet. Vielen Dank Kumpel. :) – NewbieCoder