title: Shape Fill color update stops Storyboard blinking animation
body: <p>My WPF application is a monitor for production systems.  The main window displays one of 3 Controls showing connection status (DOWN, LOADING, or UP).  The UP Control has several high-level Button shapes (an Ellipse in below example), representing various elements of the production system (Router, Config, Internal Connections, External Connections, ...).  The color of the object reflects the &quot;worst&quot; status of its children (or grandchildren, or great-grandchildren ...). It will also flash/blink (via Storyboard animation) if one of the children changes status.</p>
  <p>Each Button shape maps to a ColorStatus object:</p>
  <pre><code>    public class ColorStatus: INotifyPropertyChanged
      {
          private eStatusColor StatusColor {get; set;}
          public bool          IsFlashing  {get; set;}
      
            // ...
      }
  </code></pre>
  <p>eStatusColor is an enum (INACTIVE, NORMAL, WARNING, CRITICAL), in which I use the Converter Level2Color_Converter() to change it to a SolidColorBrush (grey/green/yellow/red), and apply it to the shape Fill.  The bool IsFlashing is used to trigger an animation on the Fill color (will go from current color to StatusBlinked, which is black, then back to current color, over a span of about 1 second).  Here is an example Button shape (Router Oval):</p>
  <pre><code>                &lt;!-- Router Oval --&gt;
                  &lt;Button Grid.Column=&quot;1&quot;             Margin=&quot;0,3&quot;
                          VerticalAlignment=&quot;Center&quot;  HorizontalAlignment=&quot;Center&quot;
                          Focusable=&quot;False&quot;           ToolTip=&quot;Open Router Window&quot;
                          Command=&quot;{Binding OpenRouterWindow_Command}&quot; &gt;
                      &lt;Button.Template&gt;
                            &lt;!-- This part turns off button borders/on mouseover animations --&gt;
                          &lt;ControlTemplate TargetType=&quot;Button&quot;&gt;
                              &lt;ContentPresenter Content=&quot;{TemplateBinding Content}&quot;/&gt;
                          &lt;/ControlTemplate&gt;
                      &lt;/Button.Template&gt;
                      &lt;Grid&gt;
                          &lt;Ellipse HorizontalAlignment=&quot;Center&quot;  VerticalAlignment=&quot;Center&quot; 
                                   Height=&quot;60&quot;                   Width=&quot;155&quot;
                                   Stroke=&quot;Black&quot;                StrokeThickness=&quot;2&quot;
                                   Fill=&quot;{Binding RouterStatus.StatusColor, 
                                         Converter={local:Level2Color_Converter}}&quot;&gt;
                              &lt;Ellipse.Style&gt;
                                  &lt;Style TargetType=&quot;{x:Type Ellipse}&quot;&gt;
                                      &lt;Style.Triggers&gt;
                                          &lt;DataTrigger Binding=&quot;{Binding RouterStatus.IsFlashing}&quot; Value=&quot;True&quot;&gt;
                                              &lt;DataTrigger.EnterActions&gt;
                                                  &lt;BeginStoryboard Name=&quot;Router_storyboard&quot;&gt;
                                                      &lt;BeginStoryboard.Storyboard&gt;
                                                          &lt;Storyboard&gt;
                                                              &lt;ColorAnimation To=&quot;{StaticResource StatusBlinked}&quot; 
                                                                              Storyboard.TargetProperty=&quot;(Path.Fill).(SolidColorBrush.Color)&quot; 
                                                                              AutoReverse=&quot;True&quot;
                                                                              RepeatBehavior=&quot;Forever&quot;
                                                                              Duration=&quot;0:0:0.5&quot;/&gt;
                                                          &lt;/Storyboard&gt;
                                                      &lt;/BeginStoryboard.Storyboard&gt;
                                                  &lt;/BeginStoryboard&gt;
                                              &lt;/DataTrigger.EnterActions&gt;
                                          &lt;/DataTrigger&gt;
                                          &lt;DataTrigger Binding=&quot;{Binding RouterStatus.IsFlashing}&quot; Value=&quot;False&quot;&gt;
                                              &lt;DataTrigger.EnterActions&gt;
                                                  &lt;StopStoryboard BeginStoryboardName=&quot;Router_storyboard&quot;/&gt;
                                              &lt;/DataTrigger.EnterActions&gt;
                                          &lt;/DataTrigger&gt;
                                      &lt;/Style.Triggers&gt;
                                  &lt;/Style&gt;
                              &lt;/Ellipse.Style&gt;
                          &lt;/Ellipse&gt;
                          &lt;TextBlock VerticalAlignment=&quot;Center&quot; HorizontalAlignment=&quot;Center&quot; 
                                     FontFamily=&quot;Arial&quot;         FontSize=&quot;13&quot;
                                     Foreground=&quot;White&quot;         Text=&quot;ROUTER&quot;&gt;
                              &lt;TextBlock.Effect&gt;
                                  &lt;DropShadowEffect/&gt;
                              &lt;/TextBlock.Effect&gt;
                          &lt;/TextBlock&gt;
                      &lt;/Grid&gt;
                  &lt;/Button&gt;
  </code></pre>
  <p>The problem is, if the object is already blinking and you change the color (say, from yellow to red), it turns off the storyboard animation (even though the bool IsFlashing is still true).</p>
  <p>In manual testing (I had a test window with buttons to force color/flashing status changes), I solved this in the following way:</p>
  <pre><code>            if (mockup_IsBlinking)
              {
                    // Toggle is blinking to keep it blinking
                  mockup_IsBlinking = false;
                  mockup_IsBlinking = true;
              }
  </code></pre>
  <p>That is, if it was flashing, turn flashing off then on again to restart the animation.</p>
  <p>For real testing (getting status updates from the application I am monitoring), I modified the ColorStatus to simulate the same method by modifying the setter:</p>
  <pre><code>    public class ColorStatus: INotifyPropertyChanged
      {
          private eStatusColor _StatusColor;
          public  eStatusColor  StatusColor {   get
                                                {
                                                    return _StatusColor;
                                                }
                                                set 
                                                { 
                                                    _StatusColor = value; 
                                                    if (IsFlashing)
                                                    {
                                                        IsFlashing = false;
                                                        IsFlashing = true;
                                                    }
                                                }     
                                            }
          public bool         IsFlashing    {get; set;}
      
            // ...
      }
  </code></pre>
  <p>BUT, when I connect to the actual application I am monitoring, I believe the blast of children status updates come in so fast that the animation gets out of sync (we get 135 children adds as NORMAL, which causes top-level Button shape from INACTIVE to NORMAL with IsFlashing=false, then actual child status updates come in, with 3 NORMAL to WARNING with IsFlashing=true and 27 NORMAL to CRITICAL with IsFlashing=true).  When I start the monitor, ~ 1/5 of the time the top level flashing is correct (blinking), 4/5 of the time it is incorrect (IsFlashing is true, but storyboard animation is not working).</p>
  <p>Note, there is not fixed order in the receipt of children statuses (we get the in the order
  they are sent from the production app).  Also note, this is a multi-threaded app (reader thread enqueues
  message to message handler thread, which updates the ViewModel, and GUI updates via INotifyPropertyChanged).</p>
  <p>Is there a way to fix this such that the Storyboard animation continues if IsFlashing is true, regardless of Fill color change? (or not get out of synch on color change?)</p>