How to display a Labels 'Error on ErrorProvide

2019-02-26 16:27发布

Goal

I want to display the text that I put in the Label's "Error on ErrorProvider1" attribute whenever I get an error. See the following label's attributes below.

Error on ErrorProvider1

I try to display the text in the red rectangle into my ErrorProvider1 SetError(control, value) function.

 If TextBox1.Text.Trim.Contains("'") Then
    ErrorProvider1.SetError(lblErr, ErrorProvider1.GetError(lblErr))
Else
    ErrorProvider1.SetError(lblErr, "")
End If

How can I retrieve the 'Error on ErrorProvider1' text from the lblErr to display it in the ErrorProvider1 SetError value?

2条回答
▲ chillily
2楼-- · 2019-02-26 16:37

Your issue is that you are replacing the error message when nothing is wrong. As noted in your comment below, you are storing the localized error message in the label's Tag, so you can do the following:

If TextBox1.Text.Trim.Contains("'") Then
    ErrorProvider1.SetError(lblErr, lblErr.Tag)
Else
    ErrorProvider1.SetError(lblErr, "")
End If

You were correct to use ErrorProvider1.GetError(Control) to get the value. It's just that you're more than likely replacing it with an empty string before you were retrieving it.

查看更多
Rolldiameter
3楼-- · 2019-02-26 16:38

The ErrorProvider component is very awkward to use effectively. It is fixable however, I'll give an example in C# that extends the component with some new capabilities:

  • ShowError(Control ctl, bool enable) displays the text that you entered at design-time when the enable argument is true. The easier-to-use version of SetError().
  • HasErrors returns true if the any active warning icons are displayed. Handy in your OK button's Click event handler.
  • FocusError() sets the focus to the first control that has a warning icon, if any. It returns false if no warnings are remaining.
  • SetError() is a replacement of ErrorProvider.SetError(). You only need it if you add any controls after the form's Load event fired or if you need to modify the warning text.

Add a new class to your project and paste the code shown below. Compile. Drop it from the top of the toolbox onto the form. The design-time behavior is identical. Modestly tested.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using System.ComponentModel.Design;

class MyErrorProvider : ErrorProvider {
    public void ShowError(Control ctl, bool enable) {
        // Easy to use version of SetError(), uses design-time text
        if (!enable) base.SetError(ctl, "");
        else {
            if (errors.ContainsKey(ctl)) base.SetError(ctl, errors[ctl]);
            else base.SetError(ctl, "No error text available");
        }
    }

    public bool HasErrors {
        // True if any errors are present
        get {
            foreach (var err in errors)
                if (!string.IsNullOrEmpty(base.GetError(err.Key))) return true;
            return false;
        }
    }

    public bool FocusError() {
        // Set the focus to the first control with an active error
        foreach (var err in errors) {
            if (!string.IsNullOrEmpty(base.GetError(err.Key))) {
                err.Key.Focus();
                return true;
            }
        }
        return false;
    }

    public new void SetError(Control ctl, string text) {
        // Use this only to add/modify error text after the form's Load event
        if (!string.IsNullOrEmpty(text)) {
            if (errors.ContainsKey(ctl)) errors[ctl] = text;
            else errors.Add(ctl, text);
        }
        base.SetError(ctl, text);
    }

    private void initialize(object sender, EventArgs e) {
        // Preserve error text
        copyErrors(((Form)sender).Controls);
    }
    private void copyErrors(Control.ControlCollection ctls) {
        foreach (Control ctl in ctls) {
            var text = this.GetError(ctl);
            if (!string.IsNullOrEmpty(text)) {
                errors.Add(ctl, text);
                base.SetError(ctl, "");
            }
            copyErrors(ctl.Controls);
        }
    }

    private Dictionary<Control, string> errors = new Dictionary<Control, string>();

    // Plumbing to hook the form's Load event
    [Browsable(false)]
    public new ContainerControl ContainerControl {
        get { return base.ContainerControl; }
        set {
            if (base.ContainerControl == null) {
                var form = value.FindForm();
                if (form != null) form.Load += initialize;
            }
            base.ContainerControl = value;
        }
    }

    public override ISite Site {
        set {
            // Runs at design time, ensures designer initializes ContainerControl
            base.Site = value;
            if (value == null) return;
            IDesignerHost service = value.GetService(typeof(IDesignerHost)) as IDesignerHost;
            if (service == null) return;
            IComponent rootComponent = service.RootComponent;
            this.ContainerControl = rootComponent as ContainerControl;
        }
    }
}
查看更多
登录 后发表回答