2016-06-22 3 views
1

私のチャットアプリケーションでは、誰かがメッセージを送信し、チャットウィンドウが開いていない場合にリストボックスに名前が点滅して、受信したメッセージをユーザーに通知するリストボックスがあります。 ユーザーがその送信者を選択した場合はアニメーションを削除していますが、アニメーションが最後に適用された要素に対してのみアニメーションが停止します。ストーリーボードアニメーションをListBoxItemに適用するのを止めるには?

以下

(選択にアニメーションを停止する)私はlistboxItem、

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); 
    } 

およびリストボックスの選択変更イベント上にアニメーションを適用するために使用していたコードである:

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); 
       } 

}

誰もが提案することができます、私は間違って何ですか? (ジャイの答えに応じて)

EDIT: -

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); 
    } 

やリストボックスのselectionchangedイベントに:

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

アニメーションが最初に適用された要素を除き、他のすべてのリストボックス項目でアニメーションが停止します。手段? – Jai

+0

アニメーションが最初に適用されたSenderName以外のすべての他の送信者のアニメーションを停止することができます(つまり、ユーザーがUserAからメッセージを取得し、その名前が点滅し、ユーザーがUserBからメッセージを受信するとしますUserBをクリックするとアニメーションが停止しますが、UserAをクリックすると点滅し続けます)。今は明らかですか? – NewbieCoder

+0

再びコードをデバッグし、最後に適用された要素のアニメーションだけが停止することを認識させてください。 – NewbieCoder

答えて

1

問題は、各ListBoxItemのために、あなたは1 Storyboardを作成しているということで、 1つのAnimationオブジェクトです。ストーリーボードとアニメーションオブジェクトは、両方とも1つのグローバルフィールドに保存されます。このようなアニメーションを複数設定すると、グローバルフィールドにはの参照が最後に追加されるアニメーション/ストーリーボードのみになります。

変更し、これに実装:

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); 
} 

アニメーションとストーリーボードのオブジェクトは再利用可能です - ので、複数のコントロールが同じアニメーションが必要な場合、それらは同じアニメーション/ストーリーボードのインスタンスを使用することができます。一度インスタンス化するだけです。私の答えでは、私はそれらを静的にしましたが、静的にしない選択肢があります。

+0

Storyboard.SetTarget(BlinkAnimation、target)のすぐ上にMyClassStaticConstructor()というNull参照例外がありました。しかし、問題はまだ同じです。アニメーションは最後の項目のためだけに終了します – NewbieCoder

+0

解決策Jaiには本当にありがとうございます。それはついに私が望むように働いています。あなたは私の一日を救った。ありがとう、たくさんの友達。 :) – NewbieCoder

関連する問題