Search code examples
vb.netwinformsvisual-studioblinkerrorprovider

How do I set the ErrorProvider blink amount?


My problem:

The red icon produced by the ErrorProvider blinks 6 times. I'd like to be able to set it to blink twice.

The only blink properties I've come across are BlinkRate and BlinkStyle, neither of which affect the blink amount.

To reproduce:

  1. In Visual Studio, in design mode, drag a TextBox and an ErrorProvider onto a fresh form.
  2. Use the following as is:

Code:

Public Class Form1
    Private Sub Textbox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
        If Not IsNumeric(TextBox1.Text) Then
            ErrorProvider1.SetError(TextBox1, "Numeric input only!")
        Else
            ErrorProvider1.SetError(TextBox1, "")
        End If
    End Sub
End Class

Solution

  • This is hard-coded in Winforms source.

    It can be messed with, if you really want to. Reflection can be used to get access to private members. Normally somewhat risky but Winforms code has been stable for a long time and isn't going to change anymore. I'll post the C# version, you can translate it to VB pretty easily:

    using System.Reflection;
    ...
        public static void ReportError(ErrorProvider provider, Control control, string text) {
            if (provider.GetError(control) == text) return;
            provider.SetError(control, text);
            // Dig out the "items" hash table to get access to the ControlItem for the control
            var fi = typeof(ErrorProvider).GetField("items", BindingFlags.NonPublic | BindingFlags.Instance);
            var ht = (System.Collections.Hashtable)(fi.GetValue(provider));
            var ci = ht[control];
            // Patch the ControlItem.blinkPhase field to lower it to 2 blinks
            var fi2 = ci.GetType().GetField("blinkPhase", BindingFlags.NonPublic | BindingFlags.Instance);
            if ((int)fi2.GetValue(ci) > 4) fi2.SetValue(ci, 4);
        }
    

    Works fine, low risk.