title: C# Winforms: User Control to blink labels in Legacy project NET 1.1
body: <p>I am trying to make a User Control to blink a label.</p>
  
  <p>I have found this <a href="https://stackoverflow.com/questions/5042516/how-to-implement-a-blinking-label-on-a-form">example</a>:</p>
  
  <pre><code>using System.Diagnostics;
  using System.Threading.Tasks;
  
  private async void SoftBlink(Control ctrl, Color c1, Color c2, short CycleTime_ms, bool BkClr)
          {
              var sw = new Stopwatch(); sw.Start();
              short halfCycle = (short)Math.Round(CycleTime_ms * 0.5);
              while (true)
              {
                  await Task.Delay(1);
                  var n = sw.ElapsedMilliseconds % CycleTime_ms;  // ERROR #1
                  var per = (double)Math.Abs(n - halfCycle) / halfCycle; 
                  var red = (short)Math.Round((c2.R - c1.R) * per) + c1.R; // ERROR #2
                  var grn = (short)Math.Round((c2.G - c1.G) * per) + c1.G; // ERROR #3
                  var blw = (short)Math.Round((c2.B - c1.B) * per) + c1.B; // ERROR #4
                  var clr = Color.FromArgb(red, grn, blw);
                  if (BkClr) ctrl.BackColor = clr; else ctrl.ForeColor = clr;
              }
          }
  </code></pre>
  
  <p>Since I want to implement it in a legacy project NET 1.1 I need to convert above piece of code to make it work so I have implemented below user control:</p>
  
  <pre><code>public class UCSoftBlink : System.Windows.Forms.Label
  {
      /// &lt;summary&gt; 
      /// Required designer variable.
      /// &lt;/summary&gt;
      private System.ComponentModel.Container components = null;
      private bool exit = false;
      private DateTime startTime = new DateTime();
      private TimeSpan elapsedTime = new TimeSpan();      
      private Timer timer = new Timer();
      private delegate void blinkingDelegate(Label lbl, Color clr1, Color clr2, short CycleTime_ms, bool bkClr);
      public static UCSoftBlink _ucSoftBlink;
  
      private UCSoftBlink()
      {
          // This call is required by the Windows.Forms Form Designer.
          InitializeComponent();
  
          timer.Tick += new EventHandler( timer_Tick );
          timer.Interval = (1000) * (1); 
          timer.Enabled = true; 
      }
  
      public static void StartBlinking(Label lbl, Color clr1, Color clr2, short CycleTime_ms, bool bkClr)
      {
          _ucSoftBlink = new UCSoftBlink();
  
          blinkingDelegate bd = new blinkingDelegate(_ucSoftBlink.Blink);
          bd.BeginInvoke(lbl, clr1, clr2, CycleTime_ms, bkClr, null, null);
      }
  
      public static void StopBlinking()
      {
          _ucSoftBlink.timer.Stop();
          _ucSoftBlink.exit = true;
      }
  
      private void Blink(Label lbl, Color clr1, Color clr2, short CycleTime_ms, bool bkClr)
      {
          _ucSoftBlink.timer.Start();
          _ucSoftBlink.startTime = DateTime.Now;          
  
          short halfCycle = (short)Math.Round(CycleTime_ms * 0.5);
          while (!exit)
          {
              System.Threading.Thread.Sleep(1000);
              short n = _ucSoftBlink.elapsedTime.TotalMilliseconds % CycleTime_ms; // ERROR #1
              double per = (double)Math.Abs(n - halfCycle) / halfCycle;
              short red = (short)Math.Round((clr2.R - clr1.R) * per) + clr1.R; ERROR #2
              short grn = (short)Math.Round((clr2.G - clr1.G) * per) + clr1.G; ERROR #3
              short blw = (short)Math.Round((clr2.B - clr1.B) * per) + clr1.B; ERROR #4
              Color clr = Color.FromArgb(red, grn, blw);
  
              if (bkClr) 
              {
                  lbl.BackColor = clr; 
              }
              else
              {
                  lbl.ForeColor = clr;
              }
          }
  
          Dispose(true);
      }
  
      private void timer_Tick(object sender, EventArgs e)
      { 
          _ucSoftBlink.elapsedTime = DateTime.Now - _ucSoftBlink.startTime;
      }
  
      /// &lt;summary&gt; 
      /// Clean up any resources being used.
      /// &lt;/summary&gt;
      protected override void Dispose( bool disposing )
      {
          if( disposing )
          {
              if(components != null)
              {
                  _ucSoftBlink.timer.Stop();
                  _ucSoftBlink.timer.Tick -= timer_Tick; // // ERROR #5 I know this is possible in other version of NET (&gt;=2.0).
                  components.Dispose();
              }
          }
          base.Dispose( disposing );
      }
  
      #region Component Designer generated code
      /// &lt;summary&gt; 
      /// Required method for Designer support - do not modify 
      /// the contents of this method with the code editor.
      /// &lt;/summary&gt;
      private void InitializeComponent()
      {
          components = new System.ComponentModel.Container();
      }
      #endregion
  }
  </code></pre>
  
  <p>but I get some compilation errors:</p>
  
  <pre><code>ERROR #1 error CS0197: Cannot pass 'My.Controls.UCSoftBlink.elapsedTime' as ref or out, because 'My.Controls.UCSoftBlink.elapsedTime' is a marshal-by-reference class
  ERROR #1 error CS0029: Cannot implicitly convert type 'double' to 'short'
  ERROR #2 error CS0029: Cannot implicitly convert type 'int' to 'short'
  ERROR #3 error CS0029: Cannot implicitly convert type 'int' to 'short'
  ERROR #4 error CS0029: Cannot implicitly convert type 'int' to 'short'
  ERROR #5 error CS0654: Method 'sdpiu.Controles.UCSoftBlink.timer_Tick(object, System.EventArgs)' referenced without parentheses
  </code></pre>
  
  <p>I want StartBlinking, StopBlinking to be static so I can access without the need of instantiate the user control.</p>