When adding interval property for user control the whole project freeze and visual studio loading the project over again how to fix it?

Viewed 57

The original code comes from this answer:
How to animate dots in UserControl Paint event?

private void DotsTimer_Tick(object sender, EventArgs e)
{
    currentDot += 1;
    currentDot %= m_NumberOfDots;
    dotsTimer.Interval = TimerInterval;
    Invalidate();
} 

I want that the interval property will show when I'm dragging the control in form1 designer like the m_DotColor for example.

This line creates the problem in the DotsTimer_Tick event:

dotsTimer.Interval = TimerInterval;

but when I'm dragging the control now into the Form's Designer, the whole project freeze shut down and Visual Studio start over again and loading the project again.

A screenshot of the PropertyGrid, without the interval part in the tick event.
I removed the line from the Tick event. In the properties, the dot color and dot active color are listed in the properties; I want to change the Interval value in the same way.

properties without the interval line in the tick event what cause the problem

Screenshot of the control on form1 designer:

the control after dragging it in form1 designer

Now I can change the colors of the DotActiveColor and DotColor before running the program! The same I want to do with the Interval to be able to change the speed of the timer before running the program.

1 Answers

If you want to see in the designer what the animation is going to be, you can add a public Property that allows to start / stop the Timer at Design-Time.

Note that you have to initialize the backing Field of a Property to the value set as DefaultValue, as in here:

private int m_Interval = 200;

The DefaultValue attribute doesn't set the Field, it prevents the serialization of the Property value if it matches the value set as the default.


I've added a AnimationEnabled public Property that can be set in the PropertyGrid, to start and stop the animation on demand.

Do not start the Timer in the Constructor of your UserControl. If you want to see the animation when the UserControl is first created (when dropped on a Form), you may use the OnHandleCreated() override. I.e., don't start the Timer until your UC has a Handle.

Also, the System.Windows.Forms.Timer has an official maximum resolution of 55ms, though it may work at 35ms. At 55ms it's already a quite fast animation anyway.

public partial class LoadingLabel : UserControl
{
    // [...]
    private Timer dotsTimer = null;
    private int m_Interval = 200;
    // [...]

    public LoadingLabel() {
        InitializeComponent();

        components = new Container();
        dotsTimer = new Timer(components) { Interval = m_Interval };
        dotsTimer.Tick += DotsTimer_Tick;
        // [...]
    }

    // [...]
    [DefaultValue(false)]
    public bool AnimationEnabled { 
        get => dotsTimer.Enabled;
        set { 
            if (value) Start(); else Stop(); 
        }
    }

    [DefaultValue(200)]
    public int TimerInterval {
        get => m_Interval;
        set {
            value = Math.Max(55, Math.Min(value, 500));
            if (m_Interval != value) {
                m_Interval = value;
                dotsTimer.Interval = m_Interval;
            }
        }
    }

    protected override void OnHandleCreated(EventArgs e) {
        base.OnHandleCreated(e);
        SetMinSize();
        // Start the Timer here - eventually - and change the default value of 
        // AnimationEnabled to true
        // Start();
    }
    // [...]
}

This is how it looks now at Design-Time:
Starting / stopping the Timer and changing the Interval

Dots Timer at Design-Time

Related